summaryrefslogtreecommitdiffstats
path: root/js/src/tests/test262/language/statements/for-of
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /js/src/tests/test262/language/statements/for-of
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/tests/test262/language/statements/for-of')
-rw-r--r--js/src/tests/test262/language/statements/for-of/Array.prototype.Symbol.iterator.js22
-rw-r--r--js/src/tests/test262/language/statements/for-of/Array.prototype.entries.js29
-rw-r--r--js/src/tests/test262/language/statements/for-of/Array.prototype.keys.js21
-rw-r--r--js/src/tests/test262/language/statements/for-of/arguments-mapped-aliasing.js30
-rw-r--r--js/src/tests/test262/language/statements/for-of/arguments-mapped-mutation.js26
-rw-r--r--js/src/tests/test262/language/statements/for-of/arguments-mapped.js23
-rw-r--r--js/src/tests/test262/language/statements/for-of/arguments-unmapped-aliasing.js31
-rw-r--r--js/src/tests/test262/language/statements/for-of/arguments-unmapped-mutation.js27
-rw-r--r--js/src/tests/test262/language/statements/for-of/arguments-unmapped.js24
-rw-r--r--js/src/tests/test262/language/statements/for-of/array-contract-expand.js35
-rw-r--r--js/src/tests/test262/language/statements/for-of/array-contract.js23
-rw-r--r--js/src/tests/test262/language/statements/for-of/array-expand-contract.js27
-rw-r--r--js/src/tests/test262/language/statements/for-of/array-expand.js33
-rw-r--r--js/src/tests/test262/language/statements/for-of/array-key-get-error.js29
-rw-r--r--js/src/tests/test262/language/statements/for-of/array.js20
-rw-r--r--js/src/tests/test262/language/statements/for-of/body-dstr-assign-error.js53
-rw-r--r--js/src/tests/test262/language/statements/for-of/body-dstr-assign.js27
-rw-r--r--js/src/tests/test262/language/statements/for-of/body-put-error.js52
-rw-r--r--js/src/tests/test262/language/statements/for-of/break-from-catch.js33
-rw-r--r--js/src/tests/test262/language/statements/for-of/break-from-finally.js32
-rw-r--r--js/src/tests/test262/language/statements/for-of/break-from-try.js31
-rw-r--r--js/src/tests/test262/language/statements/for-of/break-label-from-catch.js37
-rw-r--r--js/src/tests/test262/language/statements/for-of/break-label-from-finally.js36
-rw-r--r--js/src/tests/test262/language/statements/for-of/break-label-from-try.js35
-rw-r--r--js/src/tests/test262/language/statements/for-of/break-label.js31
-rw-r--r--js/src/tests/test262/language/statements/for-of/break.js26
-rw-r--r--js/src/tests/test262/language/statements/for-of/browser.js0
-rw-r--r--js/src/tests/test262/language/statements/for-of/continue-from-catch.js33
-rw-r--r--js/src/tests/test262/language/statements/for-of/continue-from-finally.js34
-rw-r--r--js/src/tests/test262/language/statements/for-of/continue-from-try.js31
-rw-r--r--js/src/tests/test262/language/statements/for-of/continue-label-from-catch.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/continue-label-from-finally.js42
-rw-r--r--js/src/tests/test262/language/statements/for-of/continue-label-from-try.js37
-rw-r--r--js/src/tests/test262/language/statements/for-of/continue-label.js33
-rw-r--r--js/src/tests/test262/language/statements/for-of/continue.js26
-rw-r--r--js/src/tests/test262/language/statements/for-of/cptn-decl-abrupt-empty.js44
-rw-r--r--js/src/tests/test262/language/statements/for-of/cptn-decl-itr.js34
-rw-r--r--js/src/tests/test262/language/statements/for-of/cptn-decl-no-itr.js31
-rw-r--r--js/src/tests/test262/language/statements/for-of/cptn-expr-abrupt-empty.js45
-rw-r--r--js/src/tests/test262/language/statements/for-of/cptn-expr-itr.js35
-rw-r--r--js/src/tests/test262/language/statements/for-of/cptn-expr-no-itr.js32
-rw-r--r--js/src/tests/test262/language/statements/for-of/decl-async-fun.js21
-rw-r--r--js/src/tests/test262/language/statements/for-of/decl-async-gen.js21
-rw-r--r--js/src/tests/test262/language/statements/for-of/decl-cls.js15
-rw-r--r--js/src/tests/test262/language/statements/for-of/decl-const.js15
-rw-r--r--js/src/tests/test262/language/statements/for-of/decl-fun.js15
-rw-r--r--js/src/tests/test262/language/statements/for-of/decl-gen.js16
-rw-r--r--js/src/tests/test262/language/statements/for-of/decl-let.js15
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-assignment.js42
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-evaluation.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-fn-name-arrow.js54
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-fn-name-class.js57
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-fn-name-cover.js56
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-fn-name-fn.js56
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-fn-name-gen.js56
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-in.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-let.js42
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-order.js41
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-simple-no-strict.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-yield-expr.js54
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-yield-ident-invalid-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-yield-ident-valid.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-get-err.js50
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-nrml-close-err.js67
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-nrml-close-null.js73
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-nrml-close-skip.js62
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-nrml-close.js78
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-rtrn-close-err.js77
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-rtrn-close-null.js86
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-rtrn-close.js93
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-thrw-close-err.js72
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-thrw-close-skip.js66
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-thrw-close.js81
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-invalid.js33
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-null.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-undefined-hole.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-undefined-own.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-undefined.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-yield-expr.js56
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-yield-ident-invalid-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-yield-ident-valid.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-memberexpr-optchain-prop-ref-init.js66
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-invalid.js33
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-null.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-undefined-hole.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-undefined-own.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-undefined.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-yield-expr.js54
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-yield-ident-invalid-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-yield-ident-valid.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-const.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-let.js41
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-obj-literal-optchain-prop-ref-init.js69
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-obj-literal-prop-ref-init-active.js79
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-obj-literal-prop-ref-init.js79
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-obj-literal-prop-ref.js79
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-prop-ref-no-get.js46
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-prop-ref-user-err.js44
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-prop-ref.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-unresolvable-no-strict.js42
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-unresolvable-strict-strict.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-target-identifier.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-target-simple-no-strict.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-target-simple-strict-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-target-yield-expr.js56
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-target-yield-invalid-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-target-yield-valid.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-elision-iter-abpt.js80
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-elision-iter-nrml-close-err.js76
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-elision-iter-nrml-close-null.js79
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-elision-iter-nrml-close-skip.js70
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-elision-iter-nrml-close.js85
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-get-err.js51
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-nrml-close-err.js76
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-nrml-close-null.js79
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-nrml-close-skip.js71
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-nrml-close.js84
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-rtrn-close-err.js91
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-rtrn-close-null.js91
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-rtrn-close.js102
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-thrw-close-err.js84
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-thrw-close-skip.js75
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-thrw-close.js87
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-nrml-close-skip.js71
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-rtrn-close-err.js93
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-rtrn-close-null.js88
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-rtrn-close.js99
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-thrw-close-err.js85
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-thrw-close-skip.js78
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-thrw-close.js89
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elision-iter-abpt.js66
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elision-iter-get-err.js49
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elision-iter-nrml-close-err.js69
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elision-iter-nrml-close-null.js73
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elision-iter-nrml-close-skip.js63
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elision-iter-nrml-close.js78
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-array.js37
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-bool.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-null.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-num.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-string.js37
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-symbol.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-undef.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-empty-iter-close-err.js65
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-empty-iter-close-null.js67
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-empty-iter-close.js74
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-empty-iter-get-err.js49
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-array.js37
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-bool.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-null.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-num.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-string.js37
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-symbol.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-undef.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-iteration.js45
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-after-element.js41
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-after-elision.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-before-element.js33
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-before-elision.js33
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-before-rest.js33
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-elision-invalid.js33
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-elision-iter-abpt.js71
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-elision.js41
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-init.js34
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-get-err.js50
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-nrml-close-skip.js65
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-rtrn-close-err.js88
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-rtrn-close-null.js88
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-rtrn-close.js103
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-thrw-close-err.js85
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-thrw-close-skip.js68
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-thrw-close.js93
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-iteration.js46
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-lref-err.js77
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-lref.js74
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-invalid.js33
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-iter-thrw-close-skip.js80
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-null.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-undefined-hole.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-undefined-own.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-undefined.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-yield-expr.js56
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-yield-ident-invalid-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-yield-ident-valid.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-invalid.js33
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-null.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-undefined-hole.js42
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-undefined-own.js42
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-undefined.js42
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-yield-expr.js54
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-yield-ident-invalid-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-yield-ident-valid.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-const.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-let.js41
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-prop-ref-no-get.js49
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-prop-ref-user-err-iter-close-skip.js83
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-prop-ref-user-err.js44
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-prop-ref.js41
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-unresolvable-no-strict.js42
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-unresolvable-strict-strict.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-yield-expr.js58
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-yield-ident-invalid-strict.js35
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/array-rest-yield-ident-valid.js42
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/browser.js0
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-init-iter-close.js72
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-init-iter-get-err-array-prototype.js63
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-init-iter-get-err.js57
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-init-iter-no-close.js72
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-name-iter-val.js71
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-elem-init.js63
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-elem-iter.js64
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-elision-init.js70
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-elision-iter.js67
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-empty-init.js66
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-empty-iter.js63
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-rest-init.js67
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-rest-iter.js70
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-val-null.js64
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-exhausted.js62
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-fn-name-arrow.js63
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-fn-name-class.js65
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-fn-name-cover.js64
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-fn-name-fn.js64
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-fn-name-gen.js65
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-hole.js58
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-skipped.js67
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-throws.js55
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-undef.js61
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-unresolvable.js62
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-iter-complete.js65
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-iter-done.js60
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-iter-step-err.js64
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-iter-val-array-prototype.js81
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-iter-val-err.js75
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-iter-val.js71
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-obj-id-init.js63
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-obj-id.js63
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-obj-prop-id-init.js73
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-obj-prop-id.js73
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-obj-val-null.js64
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-obj-val-undef.js64
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elision-exhausted.js68
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elision-iter-close.js54
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elision-step-err.js71
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elision.js77
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-empty.js60
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-init-err.js18
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-ary-elem.js84
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-ary-elision.js90
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-ary-empty.js73
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-ary-rest.js69
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-direct.js64
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-elision-next-err.js57
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-elision.js65
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-exhausted.js61
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-iter-close.js54
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-iter-step-err.js68
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-iter-val-err.js70
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id.js62
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-init-ary.js58
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-init-id.js58
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-init-obj.js58
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-not-final-ary.js58
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-not-final-id.js58
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-not-final-obj.js58
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-obj-id.js62
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-obj-prop-id.js69
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-init-null.js51
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-init-undefined.js51
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-empty.js61
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-get-value-err.js58
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-fn-name-arrow.js62
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-fn-name-class.js64
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-fn-name-cover.js63
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-fn-name-fn.js63
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-fn-name-gen.js64
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-skipped.js66
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-throws.js58
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-unresolvable.js62
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-trailing-comma.js56
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-init-err.js18
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-list-err.js59
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-ary-init.js65
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-ary-trailing-comma.js56
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-ary-value-null.js53
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-ary.js63
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-eval-err.js55
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id-get-value-err.js60
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id-init-skipped.js78
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id-init-throws.js58
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id-init-unresolvable.js62
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id-init.js59
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id-trailing-comma.js60
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id.js59
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-obj-init.js65
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-obj-value-null.js53
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-obj-value-undef.js53
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-obj.js63
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-rest-getter.js58
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-rest-skip-non-enumerable.js66
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-rest-val-obj.js65
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-init-iter-close.js72
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-init-iter-get-err-array-prototype.js63
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-init-iter-get-err.js57
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-init-iter-no-close.js72
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-name-iter-val.js71
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-elem-init.js63
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-elem-iter.js64
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-elision-init.js70
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-elision-iter.js67
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-empty-init.js66
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-empty-iter.js63
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-rest-init.js67
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-rest-iter.js70
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-val-null.js64
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-exhausted.js62
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-fn-name-arrow.js63
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-fn-name-class.js65
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-fn-name-cover.js64
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-fn-name-fn.js64
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-fn-name-gen.js65
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-hole.js58
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-skipped.js67
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-throws.js55
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-undef.js61
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-unresolvable.js62
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-iter-complete.js65
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-iter-done.js60
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-iter-step-err.js64
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-iter-val-array-prototype.js81
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-iter-val-err.js75
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-iter-val.js71
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-obj-id-init.js63
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-obj-id.js63
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-obj-prop-id-init.js73
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-obj-prop-id.js73
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-obj-val-null.js64
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-obj-val-undef.js64
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elision-exhausted.js68
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elision-iter-close.js55
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elision-step-err.js71
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elision.js77
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-empty.js60
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-init-err.js18
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-ary-elem.js84
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-ary-elision.js90
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-ary-empty.js73
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-ary-rest.js69
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-direct.js64
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-elision-next-err.js57
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-elision.js65
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-exhausted.js61
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-iter-close.js55
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-iter-step-err.js68
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-iter-val-err.js70
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id.js62
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-init-ary.js58
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-init-id.js58
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-init-obj.js58
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-not-final-ary.js58
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-not-final-id.js58
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-not-final-obj.js58
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-obj-id.js62
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-obj-prop-id.js69
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-init-null.js51
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-init-undefined.js51
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-empty.js61
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-get-value-err.js58
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-fn-name-arrow.js62
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-fn-name-class.js64
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-fn-name-cover.js63
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-fn-name-fn.js63
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-fn-name-gen.js64
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-skipped.js66
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-throws.js58
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-unresolvable.js62
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-trailing-comma.js56
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-init-err.js18
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-list-err.js59
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-ary-init.js65
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-ary-trailing-comma.js56
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-ary-value-null.js53
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-ary.js63
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-eval-err.js55
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id-get-value-err.js60
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id-init-skipped.js78
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id-init-throws.js58
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id-init-unresolvable.js62
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id-init.js59
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id-trailing-comma.js60
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id.js59
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-obj-init.js65
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-obj-value-null.js53
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-obj-value-undef.js53
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-obj.js63
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-rest-getter.js58
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-rest-skip-non-enumerable.js66
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-rest-val-obj.js65
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-empty-bool.js37
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-empty-null.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-empty-num.js37
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-empty-obj.js37
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-empty-string.js37
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-empty-symbol.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-empty-undef.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-resolution-first.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-resolution-last.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-resolution-lone.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-resolution-middle.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-resolution-trlng.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-yield-expr.js36
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-yield-ident-invalid-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-yield-ident-valid.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-assignment-missing.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-assignment-null.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-assignment-truthy.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-assignment-undef.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-evaluation.js41
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-fn-name-arrow.js53
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-fn-name-class.js56
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-fn-name-cover.js55
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-fn-name-fn.js55
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-fn-name-gen.js55
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-in.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-let.js42
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-order.js41
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-simple-no-strict.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-simple-strict-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-yield-expr.js54
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-yield-ident-invalid-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-yield-ident-valid.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-put-const.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-put-let.js41
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-put-unresolvable-no-strict.js42
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-put-unresolvable-strict-strict.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-simple-no-strict.js41
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-id-simple-strict-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-assignment-missing.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-assignment-null.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-assignment-truthy.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-assignment-undef.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-evaluation.js43
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-fn-name-arrow.js54
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-fn-name-class.js57
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-fn-name-cover.js56
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-fn-name-fn.js56
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-fn-name-gen.js56
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-in.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-let.js42
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-yield-expr.js53
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-yield-ident-invalid-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-yield-ident-valid.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-memberexpr-optchain-prop-ref-init.js66
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-obj-literal-optchain-prop-ref-init.js69
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-obj-literal-prop-ref-init-active.js87
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-obj-literal-prop-ref-init.js87
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-obj-literal-prop-ref.js87
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-yield-expr.js55
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-yield-ident-invalid-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-yield-ident-valid.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-identifier-resolution-first.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-identifier-resolution-last.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-identifier-resolution-lone.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-identifier-resolution-middle.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-identifier-resolution-trlng.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-name-evaluation-error.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-name-evaluation.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array-invalid.js33
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array-null.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array-undefined-own.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array-undefined.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array-yield-expr.js54
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array-yield-ident-invalid-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array-yield-ident-valid.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj-invalid.js33
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj-null.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj-undefined-own.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj-undefined.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj-yield-expr.js54
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj-yield-ident-invalid-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj-yield-ident-valid.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-const.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-let.js41
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-order.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-prop-ref-no-get.js46
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-prop-ref-user-err.js44
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-prop-ref.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-unresolvable-no-strict.js42
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-unresolvable-strict-strict.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-rest-computed-property-no-strict.js56
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-rest-computed-property.js57
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-rest-descriptors.js55
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-rest-empty-obj.js42
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-rest-getter-abrupt-get-error.js44
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-rest-getter.js47
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-1.js50
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-1dot.js50
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-1dot0.js50
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-1e0.js50
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-array-1.js50
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-array-1e0.js51
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-string-1.js50
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-rest-not-last-element-invalid.js35
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-rest-number.js42
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-rest-order.js44
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-rest-put-const.js41
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-rest-same-name.js52
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-rest-skip-non-enumerable.js55
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-rest-str-val.js43
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-rest-symbol-val.js42
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-rest-to-property-with-setter.js49
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-rest-to-property.js46
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-rest-val-null.js41
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-rest-val-undefined.js41
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/obj-rest-valid-object.js55
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/shell.js0
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-init-iter-close.js69
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-init-iter-get-err-array-prototype.js60
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-init-iter-get-err.js54
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-init-iter-no-close.js69
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-name-iter-val.js68
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-elem-init.js60
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-elem-iter.js61
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-elision-init.js67
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-elision-iter.js64
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-empty-init.js63
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-empty-iter.js60
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-rest-init.js64
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-rest-iter.js67
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-val-null.js61
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-exhausted.js59
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-fn-name-arrow.js60
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-fn-name-class.js62
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-fn-name-cover.js61
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-fn-name-fn.js61
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-fn-name-gen.js62
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-hole.js55
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-skipped.js64
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-throws.js52
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-undef.js58
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-unresolvable.js59
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-iter-complete.js62
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-iter-done.js57
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-iter-step-err.js61
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-iter-val-array-prototype.js78
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-iter-val-err.js72
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-iter-val.js68
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-obj-id-init.js60
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-obj-id.js60
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-obj-prop-id-init.js70
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-obj-prop-id.js70
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-obj-val-null.js61
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-obj-val-undef.js61
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elision-exhausted.js65
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elision-iter-close.js52
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elision-step-err.js68
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elision.js74
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-empty.js57
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-init-err.js18
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-ary-elem.js81
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-ary-elision.js87
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-ary-empty.js70
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-ary-rest.js66
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-direct.js61
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-elision-next-err.js54
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-elision.js62
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-exhausted.js58
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-iter-close.js52
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-iter-step-err.js65
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-iter-val-err.js67
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id.js59
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-init-ary.js55
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-init-id.js55
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-init-obj.js55
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-not-final-ary.js55
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-not-final-id.js55
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-not-final-obj.js55
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-obj-id.js59
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-obj-prop-id.js66
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-init-null.js48
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-init-undefined.js48
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-empty.js58
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-get-value-err.js55
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-fn-name-arrow.js59
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-fn-name-class.js61
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-fn-name-cover.js60
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-fn-name-fn.js60
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-fn-name-gen.js61
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-skipped.js63
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-throws.js55
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-unresolvable.js59
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-trailing-comma.js53
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-init-err.js18
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-list-err.js56
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-ary-init.js62
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-ary-trailing-comma.js53
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-ary-value-null.js50
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-ary.js60
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-eval-err.js52
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id-get-value-err.js57
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id-init-skipped.js75
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id-init-throws.js55
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id-init-unresolvable.js59
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id-init.js56
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id-trailing-comma.js57
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id.js56
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-obj-init.js62
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-obj-value-null.js50
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-obj-value-undef.js50
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-obj.js60
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-rest-getter.js55
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-rest-skip-non-enumerable.js63
-rw-r--r--js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-rest-val-obj.js62
-rw-r--r--js/src/tests/test262/language/statements/for-of/escaped-of.js24
-rw-r--r--js/src/tests/test262/language/statements/for-of/float32array-mutate.js36
-rw-r--r--js/src/tests/test262/language/statements/for-of/float32array.js33
-rw-r--r--js/src/tests/test262/language/statements/for-of/float64array-mutate.js36
-rw-r--r--js/src/tests/test262/language/statements/for-of/float64array.js33
-rw-r--r--js/src/tests/test262/language/statements/for-of/generator-close-via-break.js49
-rw-r--r--js/src/tests/test262/language/statements/for-of/generator-close-via-continue.js67
-rw-r--r--js/src/tests/test262/language/statements/for-of/generator-close-via-return.js51
-rw-r--r--js/src/tests/test262/language/statements/for-of/generator-close-via-throw.js51
-rw-r--r--js/src/tests/test262/language/statements/for-of/generator-next-error.js24
-rw-r--r--js/src/tests/test262/language/statements/for-of/generator.js26
-rw-r--r--js/src/tests/test262/language/statements/for-of/generic-iterable.js30
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-const-bound-names-dup.js18
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-const-bound-names-fordecl-tdz.js14
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-const-bound-names-in-stmt.js20
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-const-bound-names-let.js18
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-const-fresh-binding-per-iteration.js21
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-const-init.js18
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-decl-no-expr.js18
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-expr-no-expr.js19
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-expr-obj-iterator-method.js15
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-expr-primitive-iterator-method.js19
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-expr-to-obj.js19
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-let-bound-names-dup.js18
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-let-bound-names-fordecl-tdz.js14
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-let-bound-names-in-stmt.js20
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-let-bound-names-let.js18
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-let-destructuring.js30
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-let-fresh-binding-per-iteration.js21
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-let-init.js18
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-lhs-async-dot.js17
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-lhs-async-escaped.js20
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-lhs-async-invalid.js18
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-lhs-async-parens.js20
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-lhs-cover-non-asnmt-trgt.js25
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-lhs-cover.js21
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-lhs-invalid-asnmt-ptrn-ary.js21
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-lhs-invalid-asnmt-ptrn-obj.js21
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-lhs-let.js26
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-lhs-member.js21
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-lhs-non-asnmt-trgt.js19
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-var-bound-names-dup.js19
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-var-bound-names-in-stmt.js20
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-var-bound-names-let.js20
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-var-init.js18
-rw-r--r--js/src/tests/test262/language/statements/for-of/head-var-no-expr.js18
-rw-r--r--js/src/tests/test262/language/statements/for-of/int16array-mutate.js36
-rw-r--r--js/src/tests/test262/language/statements/for-of/int16array.js31
-rw-r--r--js/src/tests/test262/language/statements/for-of/int32array-mutate.js36
-rw-r--r--js/src/tests/test262/language/statements/for-of/int32array.js31
-rw-r--r--js/src/tests/test262/language/statements/for-of/int8array-mutate.js36
-rw-r--r--js/src/tests/test262/language/statements/for-of/int8array.js31
-rw-r--r--js/src/tests/test262/language/statements/for-of/iterator-as-proxy.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/iterator-close-non-object.js34
-rw-r--r--js/src/tests/test262/language/statements/for-of/iterator-close-non-throw-get-method-abrupt.js49
-rw-r--r--js/src/tests/test262/language/statements/for-of/iterator-close-non-throw-get-method-is-null.js49
-rw-r--r--js/src/tests/test262/language/statements/for-of/iterator-close-non-throw-get-method-non-callable.js49
-rw-r--r--js/src/tests/test262/language/statements/for-of/iterator-close-throw-get-method-abrupt.js48
-rw-r--r--js/src/tests/test262/language/statements/for-of/iterator-close-throw-get-method-non-callable.js48
-rw-r--r--js/src/tests/test262/language/statements/for-of/iterator-close-via-break.js48
-rw-r--r--js/src/tests/test262/language/statements/for-of/iterator-close-via-continue.js66
-rw-r--r--js/src/tests/test262/language/statements/for-of/iterator-close-via-return.js50
-rw-r--r--js/src/tests/test262/language/statements/for-of/iterator-close-via-throw.js50
-rw-r--r--js/src/tests/test262/language/statements/for-of/iterator-next-error.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/iterator-next-reference.js43
-rw-r--r--js/src/tests/test262/language/statements/for-of/iterator-next-result-done-attr.js132
-rw-r--r--js/src/tests/test262/language/statements/for-of/iterator-next-result-type.js108
-rw-r--r--js/src/tests/test262/language/statements/for-of/iterator-next-result-value-attr-error.js47
-rw-r--r--js/src/tests/test262/language/statements/for-of/iterator-next-result-value-attr.js50
-rw-r--r--js/src/tests/test262/language/statements/for-of/labelled-fn-stmt-const.js19
-rw-r--r--js/src/tests/test262/language/statements/for-of/labelled-fn-stmt-let.js19
-rw-r--r--js/src/tests/test262/language/statements/for-of/labelled-fn-stmt-lhs.js19
-rw-r--r--js/src/tests/test262/language/statements/for-of/labelled-fn-stmt-var.js19
-rw-r--r--js/src/tests/test262/language/statements/for-of/let-array-with-newline.js22
-rw-r--r--js/src/tests/test262/language/statements/for-of/let-block-with-newline.js18
-rw-r--r--js/src/tests/test262/language/statements/for-of/let-identifier-with-newline.js18
-rw-r--r--js/src/tests/test262/language/statements/for-of/map-contract-expand.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/map-contract.js26
-rw-r--r--js/src/tests/test262/language/statements/for-of/map-expand-contract.js30
-rw-r--r--js/src/tests/test262/language/statements/for-of/map-expand.js35
-rw-r--r--js/src/tests/test262/language/statements/for-of/map.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/nested.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/return-from-catch.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/return-from-finally.js37
-rw-r--r--js/src/tests/test262/language/statements/for-of/return-from-try.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/return.js31
-rw-r--r--js/src/tests/test262/language/statements/for-of/scope-body-lex-boundary.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/scope-body-lex-close.js42
-rw-r--r--js/src/tests/test262/language/statements/for-of/scope-body-lex-open.js50
-rw-r--r--js/src/tests/test262/language/statements/for-of/scope-body-var-none.js50
-rw-r--r--js/src/tests/test262/language/statements/for-of/scope-head-lex-close.js46
-rw-r--r--js/src/tests/test262/language/statements/for-of/scope-head-lex-open.js40
-rw-r--r--js/src/tests/test262/language/statements/for-of/scope-head-var-none.js47
-rw-r--r--js/src/tests/test262/language/statements/for-of/set-contract-expand.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/set-contract.js25
-rw-r--r--js/src/tests/test262/language/statements/for-of/set-expand-contract.js29
-rw-r--r--js/src/tests/test262/language/statements/for-of/set-expand.js34
-rw-r--r--js/src/tests/test262/language/statements/for-of/set.js48
-rw-r--r--js/src/tests/test262/language/statements/for-of/shell.js0
-rw-r--r--js/src/tests/test262/language/statements/for-of/string-astral-truncated.js31
-rw-r--r--js/src/tests/test262/language/statements/for-of/string-astral.js31
-rw-r--r--js/src/tests/test262/language/statements/for-of/string-bmp.js29
-rw-r--r--js/src/tests/test262/language/statements/for-of/throw-from-catch.js39
-rw-r--r--js/src/tests/test262/language/statements/for-of/throw-from-finally.js38
-rw-r--r--js/src/tests/test262/language/statements/for-of/throw.js32
-rw-r--r--js/src/tests/test262/language/statements/for-of/uint16array-mutate.js36
-rw-r--r--js/src/tests/test262/language/statements/for-of/uint16array.js33
-rw-r--r--js/src/tests/test262/language/statements/for-of/uint32array-mutate.js36
-rw-r--r--js/src/tests/test262/language/statements/for-of/uint32array.js33
-rw-r--r--js/src/tests/test262/language/statements/for-of/uint8array-mutate.js36
-rw-r--r--js/src/tests/test262/language/statements/for-of/uint8array.js31
-rw-r--r--js/src/tests/test262/language/statements/for-of/uint8clampedarray-mutate.js36
-rw-r--r--js/src/tests/test262/language/statements/for-of/uint8clampedarray.js32
-rw-r--r--js/src/tests/test262/language/statements/for-of/yield-from-catch.js54
-rw-r--r--js/src/tests/test262/language/statements/for-of/yield-from-finally.js52
-rw-r--r--js/src/tests/test262/language/statements/for-of/yield-from-try.js51
-rw-r--r--js/src/tests/test262/language/statements/for-of/yield-star-from-catch.js66
-rw-r--r--js/src/tests/test262/language/statements/for-of/yield-star-from-finally.js64
-rw-r--r--js/src/tests/test262/language/statements/for-of/yield-star-from-try.js63
-rw-r--r--js/src/tests/test262/language/statements/for-of/yield-star.js53
-rw-r--r--js/src/tests/test262/language/statements/for-of/yield.js43
740 files changed, 37515 insertions, 0 deletions
diff --git a/js/src/tests/test262/language/statements/for-of/Array.prototype.Symbol.iterator.js b/js/src/tests/test262/language/statements/for-of/Array.prototype.Symbol.iterator.js
new file mode 100644
index 0000000000..58fb131db5
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/Array.prototype.Symbol.iterator.js
@@ -0,0 +1,22 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ The method should return a valid iterator that can be traversed using a
+ `for...of` loop.
+es6id: 22.1.3.30
+features: [Symbol.iterator]
+---*/
+
+var array = [0, 'a', true, false, null, /* hole */, undefined, NaN];
+var i = 0;
+
+for (var value of array[Symbol.iterator]()) {
+ assert.sameValue(value, array[i], 'element at index ' + i);
+ i++;
+}
+
+assert.sameValue(i, 8, 'Visits all elements');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/Array.prototype.entries.js b/js/src/tests/test262/language/statements/for-of/Array.prototype.entries.js
new file mode 100644
index 0000000000..82e747d4b0
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/Array.prototype.entries.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+ description: >
+ The method should return a valid iterator that can be traversed using a
+ `for...of` loop.
+ es6id: 22.1.3.4
+---*/
+
+var array = [0, 'a', true, false, null, /* hole */, undefined, NaN];
+var i = 0;
+
+for (var value of array.entries()) {
+ assert.sameValue(
+ value[0], i, 'element at index ' + i + ': value (array key)'
+ );
+ assert.sameValue(
+ value[1], array[i], 'element at index ' + i + ': value (array value)'
+ );
+ assert.sameValue(
+ value.length, 2, 'element at index ' + i + ': value (array length)'
+ );
+ i++;
+}
+
+assert.sameValue(i, 8, 'Visits all elements');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/Array.prototype.keys.js b/js/src/tests/test262/language/statements/for-of/Array.prototype.keys.js
new file mode 100644
index 0000000000..2c71795448
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/Array.prototype.keys.js
@@ -0,0 +1,21 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+ description: >
+ The method should return a valid iterator that can be traversed using a
+ `for...of` loop.
+ es6id: 22.1.3.13
+---*/
+
+var array = [0, 'a', true, false, null, /* hole */, undefined, NaN];
+var i = 0;
+
+for (var value of array.keys()) {
+ assert.sameValue(value, i, 'element at index ' + i);
+ i++;
+}
+
+assert.sameValue(i, 8, 'Visits all elements');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/arguments-mapped-aliasing.js b/js/src/tests/test262/language/statements/for-of/arguments-mapped-aliasing.js
new file mode 100644
index 0000000000..5464686c0b
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/arguments-mapped-aliasing.js
@@ -0,0 +1,30 @@
+// 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
+description: >
+ Mapped arguments object mutation via alias during traversal using for..of
+info: |
+ "Mapped" arguments objects should be able to be traversed using a `for..of`
+ loop, and dynamic changes to the formal parameters should be reflected in
+ the iterated values.
+flags: [noStrict]
+---*/
+
+var expected = [1, 3, 1];
+var i = 0;
+
+(function(a, b, c) {
+ for (var value of arguments) {
+ a = b;
+ b = c;
+ c = i;
+ assert.sameValue(value, expected[i], 'argument at index ' + i);
+ i++;
+ }
+
+}(1, 2, 3));
+
+assert.sameValue(i, 3, 'Visits all arguments');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/arguments-mapped-mutation.js b/js/src/tests/test262/language/statements/for-of/arguments-mapped-mutation.js
new file mode 100644
index 0000000000..283033dc01
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/arguments-mapped-mutation.js
@@ -0,0 +1,26 @@
+// 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
+description: Mapped arguments object mutation during traversal using for..of
+info: |
+ "Mapped" arguments objects should be able to be traversed using a `for..of`
+ loop, and dynamic changes to their contents should be reflected in the
+ iterated values.
+flags: [noStrict]
+---*/
+
+var expected = [1, 4, 6];
+var i = 0;
+
+(function() {
+ for (var value of arguments) {
+ assert.sameValue(value, expected[i], 'argument at index ' + i);
+ i++;
+ arguments[i] *= 2;
+ }
+}(1, 2, 3));
+
+assert.sameValue(i, 3, 'Visits all arguments');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/arguments-mapped.js b/js/src/tests/test262/language/statements/for-of/arguments-mapped.js
new file mode 100644
index 0000000000..236677f921
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/arguments-mapped.js
@@ -0,0 +1,23 @@
+// 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
+description: Mapped arguments object traversal using for..of
+info: |
+ "Mapped" arguments objects should be able to be traversed using a `for..of`
+ loop.
+flags: [noStrict]
+---*/
+
+var i = 0;
+
+(function() {
+ for (var value of arguments) {
+ assert.sameValue(value, arguments[i], 'argument at index ' + i);
+ i++;
+ }
+}(0, 'a', true, false, null, undefined, NaN));
+
+assert.sameValue(i, 7, 'Visits all arguments');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/arguments-unmapped-aliasing.js b/js/src/tests/test262/language/statements/for-of/arguments-unmapped-aliasing.js
new file mode 100644
index 0000000000..bb4aefac27
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/arguments-unmapped-aliasing.js
@@ -0,0 +1,31 @@
+// 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
+description: >
+ Unmapped arguments object mutation via alias during traversal using for..of
+info: |
+ "Unmapped" arguments objects should be able to be traversed using a
+ `for..of` loop, and dynamic changes to the formal parameters should not be
+ reflected in the iterated values.
+flags: [noStrict]
+---*/
+
+var expected = [1, 2, 3];
+var i = 0;
+
+(function(a, b, c) {
+ 'use strict';
+ for (var value of arguments) {
+ a = b;
+ b = c;
+ c = i;
+ assert.sameValue(value, expected[i], 'argument at index ' + i);
+ i++;
+ }
+
+}(1, 2, 3));
+
+assert.sameValue(i, 3, 'Visits all arguments');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/arguments-unmapped-mutation.js b/js/src/tests/test262/language/statements/for-of/arguments-unmapped-mutation.js
new file mode 100644
index 0000000000..a3feb3ea63
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/arguments-unmapped-mutation.js
@@ -0,0 +1,27 @@
+// 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
+description: Unmapped arguments object mutation during traversal using for..of
+info: |
+ "Unmapped" arguments objects should be able to be traversed using a
+ `for..of` loop, and dynamic changes to their contents should be reflected
+ in the iterated values.
+flags: [noStrict]
+---*/
+
+var expected = [1, 4, 6];
+var i = 0;
+
+(function() {
+ 'use strict';
+ for (var value of arguments) {
+ assert.sameValue(value, expected[i], 'argument at index ' + i);
+ i++;
+ arguments[i] *= 2;
+ }
+}(1, 2, 3));
+
+assert.sameValue(i, 3, 'Visits all arguments');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/arguments-unmapped.js b/js/src/tests/test262/language/statements/for-of/arguments-unmapped.js
new file mode 100644
index 0000000000..e1a68abad3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/arguments-unmapped.js
@@ -0,0 +1,24 @@
+// 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
+description: Unmapped arguments object traversal using for..of
+info: |
+ "Umapped" arguments objects should be able to be traversed using a
+ `for..of` loop.
+flags: [noStrict]
+---*/
+
+var i = 0;
+
+(function() {
+ 'use strict';
+ for (var value of arguments) {
+ assert.sameValue(value, arguments[i], 'argument at index ' + i);
+ i++;
+ }
+}(0, 'a', true, false, null, undefined, NaN));
+
+assert.sameValue(i, 7, 'Visits all arguments');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/array-contract-expand.js b/js/src/tests/test262/language/statements/for-of/array-contract-expand.js
new file mode 100644
index 0000000000..1a4c55e5a5
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/array-contract-expand.js
@@ -0,0 +1,35 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Array entry removal and re-insertion during traversal using for..of
+info: |
+ Entries removed from an Array instance during traversal should be visited
+ if they are re-inserted prior to iterator exhaustion.
+es6id: 13.6.4
+---*/
+
+var array = [0, 1];
+var iterationCount = 0;
+
+var first = 0;
+var second = 1;
+
+for (var x of array) {
+ assert.sameValue(x, first);
+
+ first = second;
+ second = null;
+
+ if (first !== null) {
+ array.pop();
+ array.push(1);
+ }
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 2);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/array-contract.js b/js/src/tests/test262/language/statements/for-of/array-contract.js
new file mode 100644
index 0000000000..e8e7a5fc56
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/array-contract.js
@@ -0,0 +1,23 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Array entry removal during traversal using for..of
+info: |
+ Entries removed from an Array instance during traversal should not be
+ visited.
+es6id: 13.6.4
+---*/
+
+var array = [0, 1];
+var iterationCount = 0;
+
+for (var x of array) {
+ assert.sameValue(x, 0);
+ array.pop();
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/array-expand-contract.js b/js/src/tests/test262/language/statements/for-of/array-expand-contract.js
new file mode 100644
index 0000000000..d4ae45a8eb
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/array-expand-contract.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Array entry insertion and removal items during traversal using for..of
+info: |
+ New entries inserted into an Array instance during traversal should not be
+ visited if they are removed prior to visitation.
+es6id: 13.6.4
+---*/
+
+var array = [0];
+var iterationCount = 0;
+
+for (var x of array) {
+ assert.sameValue(x, 0);
+
+ array.push(1);
+ array.pop();
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/array-expand.js b/js/src/tests/test262/language/statements/for-of/array-expand.js
new file mode 100644
index 0000000000..2a80716fca
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/array-expand.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Array entry insertion during traversal using for..of
+info: |
+ New entries inserted into an Array instance during traversal should be
+ visited.
+es6id: 13.6.4
+---*/
+
+var array = [0];
+var iterationCount = 0;
+
+var first = 0;
+var second = 1;
+
+for (var x of array) {
+ assert.sameValue(x, first);
+
+ first = second;
+ second = null;
+
+ if (first !== null) {
+ array.push(1);
+ }
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 2);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/array-key-get-error.js b/js/src/tests/test262/language/statements/for-of/array-key-get-error.js
new file mode 100644
index 0000000000..aef1e6a3cd
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/array-key-get-error.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Error in Array entry access during traversal using for..of
+info: |
+ If retrieving an element from the array produces an error, that error
+ should be forwarded to the run time.
+es6id: 13.6.4
+---*/
+
+var array = [];
+var iterationCount = 0;
+
+Object.defineProperty(array, '0', {
+ get: function() {
+ throw new Test262Error();
+ }
+});
+
+assert.throws(Test262Error, function() {
+ for (var value of array) {
+ iterationCount += 1;
+ }
+});
+
+assert.sameValue(iterationCount, 0, 'The loop body is not evaluated');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/array.js b/js/src/tests/test262/language/statements/for-of/array.js
new file mode 100644
index 0000000000..51d7bda74e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/array.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+ description: >
+ Array instances should be able to be traversed using a `for...of` loop.
+ es6id: 13.6.4
+---*/
+
+var array = [0, 'a', true, false, null, /* hole */, undefined, NaN];
+var i = 0;
+
+for (var value of array) {
+ assert.sameValue(value, array[i], 'element at index ' + i);
+ i++;
+}
+
+assert.sameValue(i, 8, 'Visits all elements');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/body-dstr-assign-error.js b/js/src/tests/test262/language/statements/for-of/body-dstr-assign-error.js
new file mode 100644
index 0000000000..f9a4dfd242
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/body-dstr-assign-error.js
@@ -0,0 +1,53 @@
+// Copyright (C) 2015 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-ofheadevaluation-tdznames-expr-iterationkind
+description: >
+ If the left-hand side requires a DestructuringAssignment operation and that
+ operation produces an error, the iterator should be closed and the error
+ forwarded to the runtime.
+info: |
+ ...
+ Else,
+ If lhsKind is assignment, then
+ Let status be the result of performing DestructuringAssignmentEvaluation of
+ assignmentPattern using nextValue as the argument.
+ ...
+ If status is an abrupt completion, then
+ Set the running execution context's LexicalEnvironment to oldEnv.
+ If iterationKind is enumerate, then
+ Return status.
+
+features: [destructuring-assignment, for-of, Symbol.iterator]
+---*/
+
+var callCount = 0;
+var iterationCount = 0;
+var iterable = {};
+var x = {
+ set attr(_) {
+ throw new Test262Error();
+ }
+};
+
+iterable[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { done: false, value: [0] };
+ },
+ return: function() {
+ callCount += 1;
+ }
+ }
+};
+
+assert.throws(Test262Error, function() {
+ for ([x.attr] of iterable) {
+ iterationCount += 1;
+ }
+});
+
+assert.sameValue(iterationCount, 0, 'The loop body is not evaluated');
+assert.sameValue(callCount, 1, 'Iterator is closed');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/body-dstr-assign.js b/js/src/tests/test262/language/statements/for-of/body-dstr-assign.js
new file mode 100644
index 0000000000..d720979a4a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/body-dstr-assign.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2015 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
+description: >
+ The left-hand side may take the form of a DestructuringAssignment.
+info: |
+ ...
+ Else,
+ If lhsKind is assignment, then
+ Let status be the result of performing DestructuringAssignmentEvaluation of
+ assignmentPattern using nextValue as the argument.
+
+features: [destructuring-assignment, for-of]
+---*/
+
+var iterationCount = 0;
+var x;
+
+for ([x] of [[0]]) {
+ assert.sameValue(x, 0);
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/body-put-error.js b/js/src/tests/test262/language/statements/for-of/body-put-error.js
new file mode 100644
index 0000000000..9cd32665fa
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/body-put-error.js
@@ -0,0 +1,52 @@
+// Copyright (C) 2015 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
+description: >
+ If the left-hand side is not a lexical binding and the assignment produces
+ an error, the iterator should be closed and the error forwarded to the
+ runtime.
+info: |
+ ...
+ If destructuring is false, then
+ If lhsRef is an abrupt completion, then
+ Let status be lhsRef.
+ Else if lhsKind is lexicalBinding, then
+ Let status be InitializeReferencedBinding(lhsRef, nextValue).
+ Else,
+ Let status be PutValue(lhsRef, nextValue).
+ ...
+
+features: [for-of, Symbol.iterator]
+---*/
+
+var callCount = 0;
+var iterationCount = 0;
+var iterable = {};
+var x = {
+ set attr(_) {
+ throw new Test262Error();
+ }
+};
+
+iterable[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { done: false, value: 0 };
+ },
+ return: function() {
+ callCount += 1;
+ }
+ }
+};
+
+assert.throws(Test262Error, function() {
+ for (x.attr of iterable) {
+ iterationCount += 1;
+ }
+});
+
+assert.sameValue(iterationCount, 0, 'The loop body is not evaluated');
+assert.sameValue(callCount, 1, 'Iterator is closed');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/break-from-catch.js b/js/src/tests/test262/language/statements/for-of/break-from-catch.js
new file mode 100644
index 0000000000..8c0bc856c5
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/break-from-catch.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4.13 S5.n
+description: >
+ Control flow during body evaluation should honor `break` statements within
+ the `catch` block of `try` statements.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ throw new Test262Error('This code is unreachable (following `yield` statement).');
+}
+var iterator = values();
+var i = 0;
+
+for (var x of iterator) {
+
+ try {
+ throw new Error();
+ } catch (err) {
+ i++;
+ break;
+ throw new Test262Error('This code is unreachable (following `break` statement).');
+ }
+
+ throw new Test262Error('This code is unreachable (following `try` statement).');
+}
+
+assert.sameValue(i, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/break-from-finally.js b/js/src/tests/test262/language/statements/for-of/break-from-finally.js
new file mode 100644
index 0000000000..cb4b6ce6d8
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/break-from-finally.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 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 S5.n
+description: >
+ Control flow during body evaluation should honor `break` statements within
+ `finally` blocks.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ throw new Test262Error('This code is unreachable (following `yield` statement).');
+}
+var iterator = values();
+var i = 0;
+
+for (var x of iterator) {
+ try {
+ } finally {
+ i++;
+ break;
+
+ throw new Test262Error('This code is unreachable (following `break` statement).');
+ }
+
+ throw new Test262Error('This code is unreachable (following `try` statement).');
+}
+
+assert.sameValue(i, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/break-from-try.js b/js/src/tests/test262/language/statements/for-of/break-from-try.js
new file mode 100644
index 0000000000..8d965d2a77
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/break-from-try.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4.13 S5.n
+description: >
+ Control flow during body evaluation should honor `break` statements within
+ `try` blocks.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ throw new Test262Error('This code is unreachable (following `yield` statement).');
+}
+var iterator = values();
+var i = 0;
+
+for (var x of iterator) {
+ try {
+ i++;
+ break;
+
+ throw new Test262Error('This code is unreachable (following `break` statement).');
+ } catch (err) {}
+
+ throw new Test262Error('This code is unreachable (following `try` statement).');
+}
+
+assert.sameValue(i, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/break-label-from-catch.js b/js/src/tests/test262/language/statements/for-of/break-label-from-catch.js
new file mode 100644
index 0000000000..58a51aa76c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/break-label-from-catch.js
@@ -0,0 +1,37 @@
+// Copyright (C) 2015 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 S5.n
+description: >
+ Control flow during body evaluation should honor `break` statements within
+ `try` blocks.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ throw new Test262Error('This code is unreachable (following `yield` statement).');
+}
+var iterator = values();
+var i = 0;
+
+outer:
+while (true) {
+ for (var x of iterator) {
+ try {
+ throw new Error();
+ } catch (err) {
+ i++;
+ break outer;
+ throw new Test262Error('This code is unreachable (following `break` statement).');
+ }
+
+ throw new Test262Error('This code is unreachable (following `try` statement).');
+ }
+
+ throw new Test262Error('This code is unreachable (following `for..of` statement).');
+}
+
+assert.sameValue(i, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/break-label-from-finally.js b/js/src/tests/test262/language/statements/for-of/break-label-from-finally.js
new file mode 100644
index 0000000000..dc7b2a8ac6
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/break-label-from-finally.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2015 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 S5.n
+description: >
+ Control flow during body evaluation should honor `break` statements within
+ `try` blocks.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ throw new Test262Error('This code is unreachable (following `yield` statement).');
+}
+var iterator = values();
+var i = 0;
+
+outer:
+while (true) {
+ for (var x of iterator) {
+ try {
+ } finally {
+ i++;
+ break outer;
+ throw new Test262Error('This code is unreachable (following `break` statement).');
+ }
+
+ throw new Test262Error('This code is unreachable (following `try` statement).');
+ }
+
+ throw new Test262Error('This code is unreachable (following `for..of` statement).');
+}
+
+assert.sameValue(i, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/break-label-from-try.js b/js/src/tests/test262/language/statements/for-of/break-label-from-try.js
new file mode 100644
index 0000000000..3770198653
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/break-label-from-try.js
@@ -0,0 +1,35 @@
+// Copyright (C) 2015 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 S5.n
+description: >
+ Control flow during body evaluation should honor `break` statements within
+ `try` blocks.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ throw new Test262Error('This code is unreachable (following `yield` statement).');
+}
+var iterator = values();
+var i = 0;
+
+outer:
+while (true) {
+ for (var x of iterator) {
+ try {
+ i++;
+ break outer;
+ throw new Test262Error('This code is unreachable (following `break` statement).');
+ } catch (err) {}
+
+ throw new Test262Error('This code is unreachable (following `try` statement).');
+ }
+
+ throw new Test262Error('This code is unreachable (following `for..of` statement).');
+}
+
+assert.sameValue(i, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/break-label.js b/js/src/tests/test262/language/statements/for-of/break-label.js
new file mode 100644
index 0000000000..365f1ac1a1
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/break-label.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4.13 S5.n
+description: >
+ Control flow during body evaluation should honor labeled `break`
+ statements.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ throw new Test262Error('This code is unreachable (following `yield` statement).');
+}
+var iterator = values();
+var i = 0;
+
+outer:
+while (true) {
+ for (var x of iterator) {
+ i++;
+ break outer;
+
+ throw new Test262Error('This code is unreachable (following `break` statement).');
+ }
+ throw new Test262Error('This code is unreachable (following `for..of` statement).');
+}
+
+assert.sameValue(i, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/break.js b/js/src/tests/test262/language/statements/for-of/break.js
new file mode 100644
index 0000000000..f2afcf1c3b
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/break.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4.13 S5.n
+description: >
+ Control flow during body evaluation should honor `break` statements.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ throw new Test262Error('This code is unreachable (following `yield` statement).');
+}
+var iterator = values();
+var i = 0;
+
+for (var x of iterator) {
+ i++;
+ break;
+
+ throw new Test262Error('This code is unreachable.');
+}
+
+assert.sameValue(i, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/browser.js b/js/src/tests/test262/language/statements/for-of/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/browser.js
diff --git a/js/src/tests/test262/language/statements/for-of/continue-from-catch.js b/js/src/tests/test262/language/statements/for-of/continue-from-catch.js
new file mode 100644
index 0000000000..a7f3d8f054
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/continue-from-catch.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4.13 S5.n
+description: >
+ Control flow during body evaluation should honor `continue` statements
+ within the `catch` block of `try` statements.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ yield 1;
+}
+var iterator = values();
+var i = 0;
+
+for (var x of iterator) {
+ try {
+ throw new Error();
+ } catch (err) {
+ i++;
+ continue;
+
+ throw new Test262Error('This code is unreachable (following `continue` statement).');
+ }
+
+ throw new Test262Error('This code is unreachable (following `try` statement).');
+}
+
+assert.sameValue(i, 2);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/continue-from-finally.js b/js/src/tests/test262/language/statements/for-of/continue-from-finally.js
new file mode 100644
index 0000000000..1972c7a8f2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/continue-from-finally.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2015 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 S5.n
+description: >
+ Control flow during body evaluation should honor `continue` statements
+ within the `finally` block of `try` statements.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ yield 1;
+}
+var iterator = values();
+var i = 0;
+
+for (var x of iterator) {
+ try {
+ throw new Error();
+ } catch (err) {
+ } finally {
+ i++;
+ continue;
+
+ throw new Test262Error('This code is unreachable (following `continue` statement).');
+ }
+
+ throw new Test262Error('This code is unreachable (following `try` statement).');
+}
+
+assert.sameValue(i, 2);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/continue-from-try.js b/js/src/tests/test262/language/statements/for-of/continue-from-try.js
new file mode 100644
index 0000000000..fc01a44f26
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/continue-from-try.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4.13 S5.n
+description: >
+ Control flow during body evaluation should honor `continue` statements
+ within `try` blocks.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ yield 1;
+}
+var iterator = values();
+var i = 0;
+
+for (var x of iterator) {
+ try {
+ i++;
+ continue;
+
+ throw new Test262Error('This code is unreachable (following `continue` statement).');
+ } catch (err) {}
+
+ throw new Test262Error('This code is unreachable (following `try` statement).');
+}
+
+assert.sameValue(i, 2);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/continue-label-from-catch.js b/js/src/tests/test262/language/statements/for-of/continue-label-from-catch.js
new file mode 100644
index 0000000000..1af2ed4deb
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/continue-label-from-catch.js
@@ -0,0 +1,40 @@
+// Copyright (C) 2015 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 S5.n
+description: >
+ Control flow during body evaluation should honor `continue` statements
+ within the `catch` block of `try` statements.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ yield 1;
+}
+var iterator = values();
+var loop = true;
+var i = 0;
+
+outer:
+while (loop) {
+ loop = false;
+
+ for (var x of iterator) {
+ try {
+ throw new Error();
+ } catch (err) {
+ i++;
+ continue outer;
+ throw new Test262Error('This code is unreachable (following `continue` statement).');
+ }
+
+ throw new Test262Error('This code is unreachable (following `try` statement).');
+ }
+
+ throw new Test262Error('This code is unreachable (following `for..of` statement).');
+}
+
+assert.sameValue(i, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/continue-label-from-finally.js b/js/src/tests/test262/language/statements/for-of/continue-label-from-finally.js
new file mode 100644
index 0000000000..6924e231cb
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/continue-label-from-finally.js
@@ -0,0 +1,42 @@
+// Copyright (C) 2015 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 S5.n
+description: >
+ Control flow during body evaluation should honor `continue` statements
+ within the `finally` block of `try` statements.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ yield 1;
+}
+var iterator = values();
+var loop = true;
+var i = 0;
+
+outer:
+while (loop) {
+ loop = false;
+
+ for (var x of iterator) {
+ try {
+ throw new Error();
+ } catch (err) {
+ } finally {
+ i++;
+ continue outer;
+
+ throw new Test262Error('This code is unreachable (following `continue` statement).');
+ }
+
+ throw new Test262Error('This code is unreachable (following `try` statement).');
+ }
+
+ throw new Test262Error('This code is unreachable (following `for..of` statement).');
+}
+
+assert.sameValue(i, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/continue-label-from-try.js b/js/src/tests/test262/language/statements/for-of/continue-label-from-try.js
new file mode 100644
index 0000000000..c6e546c8d9
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/continue-label-from-try.js
@@ -0,0 +1,37 @@
+// Copyright (C) 2015 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 S5.n
+description: >
+ Control flow during body evaluation should honor `continue` statements
+ within `try` blocks.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ yield 1;
+}
+var iterator = values();
+var loop = true;
+var i = 0;
+
+outer:
+while (loop) {
+ loop = false;
+ for (var x of iterator) {
+ try {
+ i++;
+ continue outer;
+ throw new Test262Error('This code is unreachable (following `continue` statement).');
+ } catch (err) {}
+
+ throw new Test262Error('This code is unreachable (following `try` statment).');
+ }
+
+ throw new Test262Error('This code is unreachable (following `for..of` statement).');
+}
+
+assert.sameValue(i, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/continue-label.js b/js/src/tests/test262/language/statements/for-of/continue-label.js
new file mode 100644
index 0000000000..ed8a7af3bf
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/continue-label.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4.13 S5.n
+description: >
+ Control flow during body evaluation should honor labeled `continue`
+ statements.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+}
+var iterator = values();
+var i = 0;
+var loop = true;
+
+outer:
+while (loop) {
+ loop = false;
+
+ for (var x of iterator) {
+ i++;
+ continue outer;
+
+ throw new Test262Error('This code is unreachable (inside for-of).');
+ }
+ throw new Test262Error('This code is unreachable (inside while).');
+}
+
+assert.sameValue(i, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/continue.js b/js/src/tests/test262/language/statements/for-of/continue.js
new file mode 100644
index 0000000000..0ded50884c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/continue.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4.13 S5.n
+description: >
+ Control flow during body evaluation should honor `continue` statements.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ yield 1;
+}
+var iterator = values();
+var i = 0;
+
+for (var x of iterator) {
+ i++;
+ continue;
+
+ throw new Test262Error('This code is unreachable.');
+}
+
+assert.sameValue(i, 2);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/cptn-decl-abrupt-empty.js b/js/src/tests/test262/language/statements/for-of/cptn-decl-abrupt-empty.js
new file mode 100644
index 0000000000..766dade109
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/cptn-decl-abrupt-empty.js
@@ -0,0 +1,44 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.7.5.11
+description: >
+ Completion value when head has a declaration and iteration is cancelled
+info: |
+ IterationStatement : for ( var ForBinding of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ForIn/OfHeadEvaluation( « »,
+ AssignmentExpression, iterate).
+ 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 of [0]) { break; }'), undefined);
+assert.sameValue(eval('2; for (var b of [0]) { 3; break; }'), 3);
+
+assert.sameValue(
+ eval('4; outer: do { for (var a of [0]) { continue outer; } } while (false)'),
+ undefined
+);
+assert.sameValue(
+ eval('5; outer: do { for (var b of [0]) { 6; continue outer; } } while (false)'),
+ 6
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/cptn-decl-itr.js b/js/src/tests/test262/language/statements/for-of/cptn-decl-itr.js
new file mode 100644
index 0000000000..4b856e30e9
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/cptn-decl-itr.js
@@ -0,0 +1,34 @@
+// 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 of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ForIn/OfHeadEvaluation( « »,
+ AssignmentExpression, iterate).
+ 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 of [0]) { }'), undefined);
+assert.sameValue(eval('2; for (var b of [0]) { 3; }'), 3);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/cptn-decl-no-itr.js b/js/src/tests/test262/language/statements/for-of/cptn-decl-no-itr.js
new file mode 100644
index 0000000000..ce739a4baf
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/cptn-decl-no-itr.js
@@ -0,0 +1,31 @@
+// 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 of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ForIn/OfHeadEvaluation( « »,
+ AssignmentExpression, iterate).
+ 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 of []) { }'), undefined);
+assert.sameValue(eval('2; for (var b of []) { 3; }'), undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/cptn-expr-abrupt-empty.js b/js/src/tests/test262/language/statements/for-of/cptn-expr-abrupt-empty.js
new file mode 100644
index 0000000000..edbded5824
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/cptn-expr-abrupt-empty.js
@@ -0,0 +1,45 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.7.5.11
+description: >
+ Completion value when head has no declaration and iteration is cancelled
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ForIn/OfHeadEvaluation( « »,
+ AssignmentExpression, iterate).
+ 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 of [0]) { break; }'), undefined);
+assert.sameValue(eval('var b; 2; for (b of [0]) { 3; break; }'), 3);
+
+assert.sameValue(
+ eval('var a; 4; outer: do { for (a of [0]) { continue outer; } } while (false)'),
+ undefined
+);
+assert.sameValue(
+ eval('var b; 5; outer: do { for (b of [0]) { 6; continue outer; } } while (false)'),
+ 6
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/cptn-expr-itr.js b/js/src/tests/test262/language/statements/for-of/cptn-expr-itr.js
new file mode 100644
index 0000000000..be34657871
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/cptn-expr-itr.js
@@ -0,0 +1,35 @@
+// 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 of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ForIn/OfHeadEvaluation( « »,
+ AssignmentExpression, iterate).
+ 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 of [0]) { }'), undefined);
+assert.sameValue(eval('var b; 2; for (b of [0]) { 3; }'), 3);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/cptn-expr-no-itr.js b/js/src/tests/test262/language/statements/for-of/cptn-expr-no-itr.js
new file mode 100644
index 0000000000..09e01617ae
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/cptn-expr-no-itr.js
@@ -0,0 +1,32 @@
+// 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 of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ForIn/OfHeadEvaluation( « »,
+ AssignmentExpression, iterate).
+ 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 of []) { }'), undefined);
+assert.sameValue(eval('var b; 2; for (b of []) { 3; }'), undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/decl-async-fun.js b/js/src/tests/test262/language/statements/for-of/decl-async-fun.js
new file mode 100644
index 0000000000..1707055e73
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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 of []) async function f() {}
diff --git a/js/src/tests/test262/language/statements/for-of/decl-async-gen.js b/js/src/tests/test262/language/statements/for-of/decl-async-gen.js
new file mode 100644
index 0000000000..b2f1effe6d
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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 of []) async function* g() {}
diff --git a/js/src/tests/test262/language/statements/for-of/decl-cls.js b/js/src/tests/test262/language/statements/for-of/decl-cls.js
new file mode 100644
index 0000000000..ced8622834
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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 of []) class C {}
diff --git a/js/src/tests/test262/language/statements/for-of/decl-const.js b/js/src/tests/test262/language/statements/for-of/decl-const.js
new file mode 100644
index 0000000000..9deec2acab
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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 of []) const y = null;
diff --git a/js/src/tests/test262/language/statements/for-of/decl-fun.js b/js/src/tests/test262/language/statements/for-of/decl-fun.js
new file mode 100644
index 0000000000..d979f255ae
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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 of []) function f() {}
diff --git a/js/src/tests/test262/language/statements/for-of/decl-gen.js b/js/src/tests/test262/language/statements/for-of/decl-gen.js
new file mode 100644
index 0000000000..a3e7652526
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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 of []) function* g() {}
diff --git a/js/src/tests/test262/language/statements/for-of/decl-let.js b/js/src/tests/test262/language/statements/for-of/decl-let.js
new file mode 100644
index 0000000000..f07110f886
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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 of []) let y;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-assignment.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-assignment.js
new file mode 100644
index 0000000000..20143823c0
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-assignment.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-init-assignment.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: If the Initializer is present and v is undefined, the Initializer should be evaluated and the result assigned to the target reference. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var v2, vNull, vHole, vUndefined, vOob;
+
+var counter = 0;
+
+for ([v2 = 10, vNull = 11, vHole = 12, vUndefined = 13, vOob = 14] of [[2, null, , undefined]]) {
+ assert.sameValue(v2, 2);
+ assert.sameValue(vNull, null);
+ assert.sameValue(vHole, 12);
+ assert.sameValue(vUndefined, 13);
+ assert.sameValue(vOob, 14);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-evaluation.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-evaluation.js
new file mode 100644
index 0000000000..bbccdbc9c8
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-evaluation.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-init-evaluation.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: The Initializer should only be evaluated if v is undefined. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var flag1 = false, flag2 = false;
+var _;
+
+var counter = 0;
+
+for ([ _ = flag1 = true, _ = flag2 = true ] of [[14]]) {
+ assert.sameValue(flag1, false);
+ assert.sameValue(flag2, true);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-fn-name-arrow.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-fn-name-arrow.js
new file mode 100644
index 0000000000..8be5d38d3d
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-fn-name-arrow.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-init-fn-name-arrow.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Assignment of function `name` attribute (ArrowFunction) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+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.
+ [...]
+
+ AssignmentElement[Yield] : DestructuringAssignmentTarget Initializeropt
+ [...] 7. If Initializer is present and value is undefined and
+ IsAnonymousFunctionDefinition(Initializer) and IsIdentifierRef of
+ DestructuringAssignmentTarget are both true, then
+ a. Let hasNameProperty be HasOwnProperty(v, "name").
+ b. ReturnIfAbrupt(hasNameProperty).
+ c. If hasNameProperty is false, perform SetFunctionName(v,
+ GetReferencedName(lref)).
+
+---*/
+var arrow;
+
+var counter = 0;
+
+for ([ arrow = () => {} ] of [[]]) {
+ verifyProperty(arrow, 'name', {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 'arrow'
+ });
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-fn-name-class.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-fn-name-class.js
new file mode 100644
index 0000000000..8defd41fb5
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-fn-name-class.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-init-fn-name-class.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Assignment of function `name` attribute (ClassExpression) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [class, destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+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.
+ [...]
+
+ AssignmentElement[Yield] : DestructuringAssignmentTarget Initializeropt
+ [...] 7. If Initializer is present and value is undefined and
+ IsAnonymousFunctionDefinition(Initializer) and IsIdentifierRef of
+ DestructuringAssignmentTarget are both true, then
+ a. Let hasNameProperty be HasOwnProperty(v, "name").
+ b. ReturnIfAbrupt(hasNameProperty).
+ c. If hasNameProperty is false, perform SetFunctionName(v,
+ GetReferencedName(lref)).
+
+---*/
+var xCls, cls, xCls2;
+
+var counter = 0;
+
+for ([ xCls = class x {}, cls = class {}, xCls2 = class { static name() {} } ] of [[]]) {
+ assert(xCls.name !== 'xCls');
+ assert(xCls2.name !== 'xCls2');
+
+ verifyProperty(cls, 'name', {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 'cls'
+ });
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-fn-name-cover.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-fn-name-cover.js
new file mode 100644
index 0000000000..3da40d6f12
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-fn-name-cover.js
@@ -0,0 +1,56 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-init-fn-name-cover.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Assignment of function `name` attribute (CoverParenthesizedExpression) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+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.
+ [...]
+
+ AssignmentElement[Yield] : DestructuringAssignmentTarget Initializeropt
+ [...] 7. If Initializer is present and value is undefined and
+ IsAnonymousFunctionDefinition(Initializer) and IsIdentifierRef of
+ DestructuringAssignmentTarget are both true, then
+ a. Let hasNameProperty be HasOwnProperty(v, "name").
+ b. ReturnIfAbrupt(hasNameProperty).
+ c. If hasNameProperty is false, perform SetFunctionName(v,
+ GetReferencedName(lref)).
+
+---*/
+var xCover, cover;
+
+var counter = 0;
+
+for ([ xCover = (0, function() {}), cover = (function() {}) ] of [[]]) {
+ assert(xCover.name !== 'xCover');
+
+ verifyProperty(cover, 'name', {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 'cover'
+ });
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-fn-name-fn.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-fn-name-fn.js
new file mode 100644
index 0000000000..803fc9cad4
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-fn-name-fn.js
@@ -0,0 +1,56 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-init-fn-name-fn.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Assignment of function `name` attribute (FunctionExpression) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [class, destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+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.
+ [...]
+
+ AssignmentElement[Yield] : DestructuringAssignmentTarget Initializeropt
+ [...] 7. If Initializer is present and value is undefined and
+ IsAnonymousFunctionDefinition(Initializer) and IsIdentifierRef of
+ DestructuringAssignmentTarget are both true, then
+ a. Let hasNameProperty be HasOwnProperty(v, "name").
+ b. ReturnIfAbrupt(hasNameProperty).
+ c. If hasNameProperty is false, perform SetFunctionName(v,
+ GetReferencedName(lref)).
+
+---*/
+var xFn, fn;
+
+var counter = 0;
+
+for ([ xFn = function x() {}, fn = function() {} ] of [[]]) {
+ assert(xFn.name !== 'xFn');
+
+ verifyProperty(fn, 'name', {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 'fn'
+ });
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-fn-name-gen.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-fn-name-gen.js
new file mode 100644
index 0000000000..dba9a58abb
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-fn-name-gen.js
@@ -0,0 +1,56 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-init-fn-name-gen.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Assignment of function `name` attribute (GeneratorExpression) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+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.
+ [...]
+
+ AssignmentElement[Yield] : DestructuringAssignmentTarget Initializeropt
+ [...] 7. If Initializer is present and value is undefined and
+ IsAnonymousFunctionDefinition(Initializer) and IsIdentifierRef of
+ DestructuringAssignmentTarget are both true, then
+ a. Let hasNameProperty be HasOwnProperty(v, "name").
+ b. ReturnIfAbrupt(hasNameProperty).
+ c. If hasNameProperty is false, perform SetFunctionName(v,
+ GetReferencedName(lref)).
+
+---*/
+var xGen, gen;
+
+var counter = 0;
+
+for ([ xGen = function* x() {}, gen = function*() {} ] of [[]]) {
+ assert.notSameValue(xGen.name, 'xGen');
+
+ verifyProperty(gen, 'name', {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 'gen'
+ });
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-in.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-in.js
new file mode 100644
index 0000000000..e96d24918c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-in.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-init-in.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: The Initializer in an AssignmentElement may be an `in` expression. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+for ([ x = 'x' in {} ] of [[]]) {
+ assert.sameValue(x, false);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-let.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-let.js
new file mode 100644
index 0000000000..b0a3900788
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-let.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-init-let.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: Value retrieval of Initializer obeys `let` semantics. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [let, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+assert.throws(ReferenceError, function() {
+ for ([ x = y ] of [[]]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+let y;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-order.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-order.js
new file mode 100644
index 0000000000..44df138ffb
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-order.js
@@ -0,0 +1,41 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-init-order.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Initializer values should be assigned in left-to-right order. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x = 0;
+var a, b;
+
+var counter = 0;
+
+for ([ a = x += 1, b = x *= 2 ] of [[]]) {
+ assert.sameValue(a, 1);
+ assert.sameValue(b, 2);
+ assert.sameValue(x, 2);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-simple-no-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-simple-no-strict.js
new file mode 100644
index 0000000000..0d27234e42
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-simple-no-strict.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-init-simple-no-strict.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Identifiers that appear as the DestructuringAssignmentTarget in an AssignmentElement should take on the iterated value corresponding to their position in the ArrayAssignmentPattern. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, noStrict]
+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.
+ [...]
+---*/
+var argument, eval;
+
+var counter = 0;
+
+for ([arguments = 4, eval = 5] of [[]]) {
+ assert.sameValue(arguments, 4);
+ assert.sameValue(eval, 5);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-yield-expr.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-yield-expr.js
new file mode 100644
index 0000000000..986b32c2a1
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-yield-expr.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-init-yield-expr.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When a `yield` token appears within the Initializer of an AssignmentElement within a generator function body, it behaves as a YieldExpression. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var value = [];
+var iterationResult, iter, x;
+iter = (function*() {
+
+var counter = 0;
+
+for ([ x = yield ] of [[]]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+})();
+
+iterationResult = iter.next();
+
+assert.sameValue(iterationResult.value, undefined);
+assert.sameValue(iterationResult.done, false);
+assert.sameValue(x, undefined);
+
+iterationResult = iter.next(86);
+
+assert.sameValue(iterationResult.value, undefined);
+assert.sameValue(iterationResult.done, true);
+assert.sameValue(x, 86);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-yield-ident-invalid-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-yield-ident-invalid-strict.js
new file mode 100644
index 0000000000..7cb9b2a429
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.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..of 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 ] of [[]]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-yield-ident-valid.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-yield-ident-valid.js
new file mode 100644
index 0000000000..8d12e33155
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-init-yield-ident-valid.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-init-yield-ident-valid.case
+// - src/dstr-assignment/default/for-of.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..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, noStrict]
+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.
+ [...]
+---*/
+var yield = 4;
+var x;
+
+var counter = 0;
+
+for ([ x = yield ] of [[]]) {
+ assert.sameValue(x, 4);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-get-err.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-get-err.js
new file mode 100644
index 0000000000..a3d0803fe6
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-get-err.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-iter-get-err.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: Abrupt completion returned from GetIterator (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ AssignmentElementList ]
+
+ 1. Let iterator be GetIterator(value).
+ 2. ReturnIfAbrupt(iterator).
+
+---*/
+var iterable = {};
+iterable[Symbol.iterator] = function() {
+ throw new Test262Error();
+};
+var _;
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([ _ ] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-nrml-close-err.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-nrml-close-err.js
new file mode 100644
index 0000000000..77e23d0684
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-nrml-close-err.js
@@ -0,0 +1,67 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-iter-nrml-close-err.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: Abrupt completion returned from IteratorClose (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ AssignmentElementList ]
+
+ [...]
+ 5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator, result).
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var _;
+var iterable = {};
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ // Set an upper-bound to limit unnecessary iteration in non-conformant
+ // implementations
+ return { done: nextCount > 10 };
+ },
+ return: function() {
+ returnCount += 1;
+ throw new Test262Error();
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([ _ ] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-nrml-close-null.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-nrml-close-null.js
new file mode 100644
index 0000000000..6cd47504a1
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-nrml-close-null.js
@@ -0,0 +1,73 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-iter-nrml-close-null.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: IteratorClose throws a TypeError when `return` returns a non-Object value (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ AssignmentElementList ]
+
+ [...]
+ 5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+ 6. Return result.
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ 7. If completion.[[type]] is throw, return Completion(completion).
+ 8. If innerResult.[[type]] is throw, return Completion(innerResult).
+ 9. If Type(innerResult.[[value]]) is not Object, throw a TypeError
+ exception.
+
+---*/
+var _;
+var iterable = {};
+var nextCount = 0;
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ // Set an upper-bound to limit unnecessary iteration in non-conformant
+ // implementations
+ return { done: nextCount > 10 };
+ },
+ return: function() {
+ return null;
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ([ _ ] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-nrml-close-skip.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-nrml-close-skip.js
new file mode 100644
index 0000000000..d6f1d8eb3e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-nrml-close-skip.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-iter-nrml-close-skip.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: IteratorClose is not called when assignment evaluation has exhausted the iterator (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ AssignmentElementList ]
+
+ [...]
+ 5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator, result).
+ 6. Return result.
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var _;
+var iterable = {};
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ return { done: true };
+ },
+ return: function() {
+ returnCount += 1;
+ return {};
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+for ([ _ ] of [iterable]) {
+ assert.sameValue(nextCount, 1);
+ assert.sameValue(returnCount, 0);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-nrml-close.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-nrml-close.js
new file mode 100644
index 0000000000..66cd1fa186
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-nrml-close.js
@@ -0,0 +1,78 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-iter-nrml-close.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: IteratorClose is called when assignment evaluation has not exhausted the iterator (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ AssignmentElementList ]
+
+ [...]
+ 5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+ 6. Return result.
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ [...]
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var thisValue = null;
+var args = null;
+var _;
+var iterable = {};
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ // Set an upper-bound to limit unnecessary iteration in non-conformant
+ // implementations
+ return { done: nextCount > 10 };
+ },
+ return: function() {
+ returnCount += 1;
+ thisValue = this;
+ args = arguments;
+ return {};
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+for ([ _ ] of [iterable]) {
+ assert.sameValue(nextCount, 1);
+ assert.sameValue(returnCount, 1);
+ assert.sameValue(thisValue, iterator, 'correct `this` value');
+ assert(!!args, 'arguments object provided');
+ assert.sameValue(args.length, 0, 'zero arguments specified');
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-rtrn-close-err.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-rtrn-close-err.js
new file mode 100644
index 0000000000..2f057606e8
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-rtrn-close-err.js
@@ -0,0 +1,77 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-iter-rtrn-close-err.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: IteratorClose is called when reference evaluation produces a "return" completion (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, generators, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ AssignmentElementList ]
+
+ [...]
+ 5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+ 6. Return result.
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ 7. If completion.[[type]] is throw, return Completion(completion).
+ 8. If innerResult.[[type]] is throw, return Completion(innerResult).
+
+---*/
+var returnCount = 0;
+var unreachable = 0;
+var iterable = {};
+var iterator = {
+ return: function() {
+ returnCount += 1;
+ throw new Test262Error();
+ }
+};
+var iter;
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+function* g() {
+
+var counter = 0;
+
+for ([ {}[ yield ] ] of [iterable]) {
+ unreachable += 1;
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+}
+iter = g();
+iter.next();
+assert.throws(Test262Error, function() {
+ iter.return();
+});
+
+assert.sameValue(returnCount, 1);
+assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-rtrn-close-null.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-rtrn-close-null.js
new file mode 100644
index 0000000000..f3fa8bfba7
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-rtrn-close-null.js
@@ -0,0 +1,86 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-iter-rtrn-close-null.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: IteratorClose throws a TypeError when `return` returns a non-Object value (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, generators, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ AssignmentElementList ]
+
+ [...]
+ 5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+ 6. Return result.
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ 7. If completion.[[type]] is throw, return Completion(completion).
+ 8. If innerResult.[[type]] is throw, return Completion(innerResult).
+ 9. If Type(innerResult.[[value]]) is not Object, throw a TypeError
+ exception.
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var unreachable = 0;
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ return {done: false, value: undefined};
+ },
+ return: function() {
+ returnCount += 1;
+ return null;
+ }
+};
+var iterable = {};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+function* g() {
+
+var counter = 0;
+
+for ([ {} = yield ] of [iterable]) {
+ unreachable += 1;
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+}
+
+var iter = g();
+iter.next();
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
+assert.throws(TypeError, function() {
+ iter.return();
+});
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 1);
+assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-rtrn-close.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-rtrn-close.js
new file mode 100644
index 0000000000..1ba48978a9
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-rtrn-close.js
@@ -0,0 +1,93 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-iter-rtrn-close.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: IteratorClose is called when reference evaluation produces a "return" completion (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, generators, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ AssignmentElementList ]
+
+ [...]
+ 5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+ 6. Return result.
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ 7. If completion.[[type]] is throw, return Completion(completion).
+ 8. If innerResult.[[type]] is throw, return Completion(innerResult).
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var unreachable = 0;
+var thisValue = null;
+var args = null;
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ return {done: false, value: undefined};
+ },
+ return: function() {
+ returnCount += 1;
+ thisValue = this;
+ args = arguments;
+ return {};
+ }
+};
+var iterable = {};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+function* g() {
+
+var counter = 0;
+
+for ([ {} = yield ] of [iterable]) {
+ unreachable += 1;
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+}
+var iter = g();
+iter.next();
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
+
+var result = iter.return(777);
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 1);
+assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
+assert.sameValue(result.value, 777);
+assert(result.done, 'Iterator correctly closed');
+assert.sameValue(thisValue, iterator, 'correct `this` value');
+assert(!!args, 'arguments object provided');
+assert.sameValue(args.length, 0, 'zero arguments specified');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-thrw-close-err.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-thrw-close-err.js
new file mode 100644
index 0000000000..7b6fffcc4c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-thrw-close-err.js
@@ -0,0 +1,72 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-iter-thrw-close-err.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: IteratorClose is called when reference evaluation produces a "throw" completion (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ AssignmentElementList ]
+
+ [...]
+ 5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+ 6. Return result.
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+function ReturnError() {}
+var iterable = {};
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ return { done: true };
+ },
+ return: function() {
+ returnCount += 1;
+
+ // This value should be discarded.
+ throw new ReturnError();
+ }
+};
+var thrower = function() {
+ throw new Test262Error();
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([ {}[thrower()] ] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+assert.sameValue(nextCount, 0);
+assert.sameValue(returnCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-thrw-close-skip.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-thrw-close-skip.js
new file mode 100644
index 0000000000..992ab88a44
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-thrw-close-skip.js
@@ -0,0 +1,66 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-iter-thrw-close-skip.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: IteratorClose is not called when iteration produces an abrupt completion (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ AssignmentElementList ]
+
+ [...]
+ 5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+ 6. Return result.
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ throw new Test262Error();
+ },
+ return: function() {
+ returnCount += 1;
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+var _;
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([ x ] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-thrw-close.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-thrw-close.js
new file mode 100644
index 0000000000..807c4cdb81
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-iter-thrw-close.js
@@ -0,0 +1,81 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-iter-thrw-close.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: IteratorClose is called when reference evaluation produces a "throw" completion (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ AssignmentElementList ]
+
+ [...]
+ 5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+ 6. Return result.
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ [...]
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var thisValue = null;
+var args = null;
+var iterable = {};
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ return { done: true };
+ },
+ return: function() {
+ returnCount += 1;
+ thisValue = this;
+ args = arguments;
+ }
+};
+var thrower = function() {
+ throw new Test262Error();
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([ {}[thrower()] ] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+assert.sameValue(nextCount, 0);
+assert.sameValue(returnCount, 1);
+assert.sameValue(thisValue, iterator, 'correct `this` value');
+assert(!!args, 'arguments object provided');
+assert.sameValue(args.length, 0, 'zero arguments specified');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-invalid.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-invalid.js
new file mode 100644
index 0000000000..8a5fc098ce
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.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..of 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)]] of [[[]]]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-null.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-null.js
new file mode 100644
index 0000000000..2b675653cb
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-null.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-nested-array-null.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an array literal and the value is `null`, a TypeError should be thrown. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var _;
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ([[ _ ]] of [[null]]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-undefined-hole.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-undefined-hole.js
new file mode 100644
index 0000000000..a204f6a461
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-undefined-hole.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-nested-array-undefined-hole.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an array literal and the value is a "hole", a TypeError should be thrown. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var _;
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ([[ _ ]] of [[ , ]]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-undefined-own.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-undefined-own.js
new file mode 100644
index 0000000000..e63ba1a3d3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-undefined-own.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-nested-array-undefined-own.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an array literal and the value is `undefined`, a TypeError should be thrown. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var _;
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ([[ x ]] of [[undefined]]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-undefined.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-undefined.js
new file mode 100644
index 0000000000..d8d5ffcb87
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-undefined.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-nested-array-undefined.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an array literal and no value is defined, a TypeError should be thrown. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var _;
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ([[ x ]] of [[]]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-yield-expr.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-yield-expr.js
new file mode 100644
index 0000000000..138133f07d
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-yield-expr.js
@@ -0,0 +1,56 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-nested-array-yield-expr.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When a `yield` token appears within the DestructuringAssignmentTarget of a nested destructuring assignment and within a generator function body, it behaves as a YieldExpression. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var value = [[22]];
+var x = {};
+var iterationResult, iter;
+
+iter = (function*() {
+
+var counter = 0;
+
+for ([[x[yield]]] of [value]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+}());
+
+iterationResult = iter.next();
+
+assert.sameValue(iterationResult.value, undefined);
+assert.sameValue(iterationResult.done, false);
+assert.sameValue(x.prop, undefined);
+
+iterationResult = iter.next('prop');
+
+assert.sameValue(iterationResult.value, undefined);
+assert.sameValue(iterationResult.done, true);
+assert.sameValue(x.prop, 22);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-yield-ident-invalid-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-yield-ident-invalid-strict.js
new file mode 100644
index 0000000000..d4a52b24fa
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.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..of 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]]] of [[[]]]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-yield-ident-valid.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-yield-ident-valid.js
new file mode 100644
index 0000000000..145115147f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array-yield-ident-valid.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-nested-array-yield-ident-valid.case
+// - src/dstr-assignment/default/for-of.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..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, noStrict]
+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.
+ [...]
+---*/
+var yield = 'prop';
+var x = {};
+
+var counter = 0;
+
+for ([[x[yield]]] of [[[22]]]) {
+ assert.sameValue(x.prop, 22);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array.js
new file mode 100644
index 0000000000..5a3dd3d619
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-array.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-nested-array.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an array literal, it should be parsed parsed as a DestructuringAssignmentPattern and evaluated as a destructuring assignment. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+for ([[x]] of [[[1]]]) {
+ assert.sameValue(x, 1);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-memberexpr-optchain-prop-ref-init.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-memberexpr-optchain-prop-ref-init.js
new file mode 100644
index 0000000000..7c69c77bbe
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.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..of 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] of [[23]]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-invalid.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-invalid.js
new file mode 100644
index 0000000000..6d366da8d7
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.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..of 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() {} }] of [[{}]]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-null.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-null.js
new file mode 100644
index 0000000000..b6864a4638
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-null.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-nested-obj-null.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an object literal and the value is `null`, a TypeError should be thrown. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ([{ x }] of [[null]]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-undefined-hole.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-undefined-hole.js
new file mode 100644
index 0000000000..a521cbca92
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-undefined-hole.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-nested-obj-undefined-hole.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an object literal and the value is a "hole", a TypeError should be thrown. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ([{ x }] of [[ , ]]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-undefined-own.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-undefined-own.js
new file mode 100644
index 0000000000..552d0751e9
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-undefined-own.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-nested-obj-undefined-own.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an object literal and the value is `undefined`, a TypeError should be thrown. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ([{ x }] of [[undefined]]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-undefined.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-undefined.js
new file mode 100644
index 0000000000..b6f0adc559
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-undefined.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-nested-obj-undefined.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an object literal and no value is defined, a TypeError should be thrown. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ([{ x }] of [[]]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-yield-expr.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-yield-expr.js
new file mode 100644
index 0000000000..e5a2a41058
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-yield-expr.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-nested-obj-yield-expr.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When a `yield` token appears within the Initializer of a nested destructuring assignment and within a generator function body, it behaves as a YieldExpression. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var iterationResult, iter, x;
+
+iter = (function*() {
+
+var counter = 0;
+
+for ([{ x = yield }] of [[{}]]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+}());
+
+iterationResult = iter.next();
+
+assert.sameValue(iterationResult.value, undefined);
+assert.sameValue(iterationResult.done, false);
+assert.sameValue(x, undefined);
+
+iterationResult = iter.next(4);
+
+assert.sameValue(iterationResult.value, undefined);
+assert.sameValue(iterationResult.done, true);
+assert.sameValue(x, 4);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-yield-ident-invalid-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-yield-ident-invalid-strict.js
new file mode 100644
index 0000000000..a7a49a4947
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.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..of 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 }] of [[{}]]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-yield-ident-valid.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-yield-ident-valid.js
new file mode 100644
index 0000000000..c3935a3ac5
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj-yield-ident-valid.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-nested-obj-yield-ident-valid.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When a `yield` token appears within the Initializer of a nested destructuring assignment outside of a generator function body, it behaves as an IdentifierReference. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, noStrict]
+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.
+ [...]
+---*/
+var yield = 2;
+var x;
+
+var counter = 0;
+
+for ([{ x = yield }] of [[{}]]) {
+ assert.sameValue(x, 2);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj.js
new file mode 100644
index 0000000000..d4c064fbd2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-nested-obj.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-nested-obj.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an object literal, it should be parsed as a DestructuringAssignmentPattern and evaluated as a destructuring assignment. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+for ([{ x }] of [[{ x: 2 }]]) {
+ assert.sameValue(x, 2);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-const.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-const.js
new file mode 100644
index 0000000000..eb90ecce08
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-const.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-put-const.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: The assignment target should obey `const` semantics. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [const, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+const c = null;
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ([ c ] of [[1]]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-let.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-let.js
new file mode 100644
index 0000000000..1347eb8ec2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-let.js
@@ -0,0 +1,41 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-put-let.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: The assignment target should obey `let` semantics. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [let, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+
+var counter = 0;
+
+assert.throws(ReferenceError, function() {
+ for ([ x ] of [[]]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+let x;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-obj-literal-optchain-prop-ref-init.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-obj-literal-optchain-prop-ref-init.js
new file mode 100644
index 0000000000..b83831dde1
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.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..of 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] of [[23]]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-obj-literal-prop-ref-init-active.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-obj-literal-prop-ref-init-active.js
new file mode 100644
index 0000000000..9f222e6814
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-obj-literal-prop-ref-init-active.js
@@ -0,0 +1,79 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-put-obj-literal-prop-ref-init-active.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: The DestructuringAssignmentTarget of an AssignmentElement can extend to LHSExpressions if it is neither an ObjectLiteral nor an ArrayLiteral and its AssignmentTargetTyp is simple. Using MemberExpression (ObjLiteral + identifier) with activated initializer. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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
+
+ AssignmentPattern : ArrayAssignmentPattern
+ ArrayAssignmentPattern : [ AssignmentElementList ]
+ AssignmentElementList : AssignmentElisionElement
+ AssignmentElisionElement : Elision_opt AssignmentElement
+ AssignmentElement : DestructuringAssignmentTarget Initializer_opt
+ DestructuringAssignmentTarget : LeftHandSideExpression
+
+ Static Semantics: Early Errors
+
+ DestructuringAssignmentTarget : LeftHandSideExpression
+
+ - It is a Syntax Error if LeftHandSideExpression is either an ObjectLiteral or an ArrayLiteral and if LeftHandSideExpression is not covering an AssignmentPattern.
+ - It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple.
+
+ Runtime Semantics: DestructuringAssignmentEvaluation
+ ArrayAssignmentPattern : [ AssignmentElementList ]
+
+ 1. Let iteratorRecord be ? GetIterator(value).
+ 2. Let result be IteratorDestructuringAssignmentEvaluation of AssignmentElementList with argument iteratorRecord.
+ 3. If iteratorRecord.[[Done]] is false, return ? IteratorClose(iteratorRecord, result).
+ 4. Return result.
+
+ Runtime Semantics: IteratorDestructuringAssignmentEvaluation
+ AssignmentElement : DestructuringAssignmentTarget Initializer
+
+ 1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral, then
+ a. Let lref be the result of evaluating DestructuringAssignmentTarget.
+ ...
+ 7. Return ? PutValue(lref, v).
+
+---*/
+var x, setValue;
+
+var counter = 0;
+
+for ([{
+ get y() {
+ throw new Test262Error('The property should not be accessed.');
+ },
+ set y(val) {
+ setValue = val;
+ }
+}.y = 42] of [[undefined]]) {
+ assert.sameValue(setValue, 42);
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-obj-literal-prop-ref-init.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-obj-literal-prop-ref-init.js
new file mode 100644
index 0000000000..3edd7eb750
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-obj-literal-prop-ref-init.js
@@ -0,0 +1,79 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-put-obj-literal-prop-ref-init.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: The DestructuringAssignmentTarget of an AssignmentElement can extend to LHSExpressions if it is neither an ObjectLiteral nor an ArrayLiteral and its AssignmentTargetTyp is simple. Using MemberExpression (ObjLiteral + identifier) with initializer. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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
+
+ AssignmentPattern : ArrayAssignmentPattern
+ ArrayAssignmentPattern : [ AssignmentElementList ]
+ AssignmentElementList : AssignmentElisionElement
+ AssignmentElisionElement : Elision_opt AssignmentElement
+ AssignmentElement : DestructuringAssignmentTarget Initializer_opt
+ DestructuringAssignmentTarget : LeftHandSideExpression
+
+ Static Semantics: Early Errors
+
+ DestructuringAssignmentTarget : LeftHandSideExpression
+
+ - It is a Syntax Error if LeftHandSideExpression is either an ObjectLiteral or an ArrayLiteral and if LeftHandSideExpression is not covering an AssignmentPattern.
+ - It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple.
+
+ Runtime Semantics: DestructuringAssignmentEvaluation
+ ArrayAssignmentPattern : [ AssignmentElementList ]
+
+ 1. Let iteratorRecord be ? GetIterator(value).
+ 2. Let result be IteratorDestructuringAssignmentEvaluation of AssignmentElementList with argument iteratorRecord.
+ 3. If iteratorRecord.[[Done]] is false, return ? IteratorClose(iteratorRecord, result).
+ 4. Return result.
+
+ Runtime Semantics: IteratorDestructuringAssignmentEvaluation
+ AssignmentElement : DestructuringAssignmentTarget Initializer
+
+ 1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral, then
+ a. Let lref be the result of evaluating DestructuringAssignmentTarget.
+ ...
+ 7. Return ? PutValue(lref, v).
+
+---*/
+var x, setValue;
+
+var counter = 0;
+
+for ([{
+ get y() {
+ throw new Test262Error('The property should not be accessed.');
+ },
+ set y(val) {
+ setValue = val;
+ }
+}.y = 42] of [[23]]) {
+ assert.sameValue(setValue, 23);
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-obj-literal-prop-ref.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-obj-literal-prop-ref.js
new file mode 100644
index 0000000000..712b25cd02
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-obj-literal-prop-ref.js
@@ -0,0 +1,79 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-put-obj-literal-prop-ref.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: The DestructuringAssignmentTarget of an AssignmentElement can extend to LHSExpressions if it is neither an ObjectLiteral nor an ArrayLiteral and its AssignmentTargetTyp is simple. Using MemberExpression (ObjLiteral + identifier). (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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
+
+ AssignmentPattern : ArrayAssignmentPattern
+ ArrayAssignmentPattern : [ AssignmentElementList ]
+ AssignmentElementList : AssignmentElisionElement
+ AssignmentElisionElement : Elision_opt AssignmentElement
+ AssignmentElement : DestructuringAssignmentTarget Initializer_opt
+ DestructuringAssignmentTarget : LeftHandSideExpression
+
+ Static Semantics: Early Errors
+
+ DestructuringAssignmentTarget : LeftHandSideExpression
+
+ - It is a Syntax Error if LeftHandSideExpression is either an ObjectLiteral or an ArrayLiteral and if LeftHandSideExpression is not covering an AssignmentPattern.
+ - It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple.
+
+ Runtime Semantics: DestructuringAssignmentEvaluation
+ ArrayAssignmentPattern : [ AssignmentElementList ]
+
+ 1. Let iteratorRecord be ? GetIterator(value).
+ 2. Let result be IteratorDestructuringAssignmentEvaluation of AssignmentElementList with argument iteratorRecord.
+ 3. If iteratorRecord.[[Done]] is false, return ? IteratorClose(iteratorRecord, result).
+ 4. Return result.
+
+ Runtime Semantics: IteratorDestructuringAssignmentEvaluation
+ AssignmentElement : DestructuringAssignmentTarget Initializer
+
+ 1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral, then
+ a. Let lref be the result of evaluating DestructuringAssignmentTarget.
+ ...
+ 7. Return ? PutValue(lref, v).
+
+---*/
+var x, setValue;
+
+var counter = 0;
+
+for ([{
+ get y() {
+ throw new Test262Error('The property should not be accessed.');
+ },
+ set y(val) {
+ setValue = val;
+ }
+}.y] of [[23]]) {
+ assert.sameValue(setValue, 23);
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-prop-ref-no-get.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-prop-ref-no-get.js
new file mode 100644
index 0000000000..b4f82d1792
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-prop-ref-no-get.js
@@ -0,0 +1,46 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-put-prop-ref-no-get.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: If the DestructuringAssignmentTarget of an AssignmentElement is a PropertyReference, it should not be evaluated. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x, setValue;
+x = {
+ get y() {
+ throw new Test262Error('The property should not be accessed.');
+ },
+ set y(val) {
+ setValue = val;
+ }
+};
+
+var counter = 0;
+
+for ([x.y] of [[23]]) {
+ assert.sameValue(setValue, 23);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-prop-ref-user-err.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-prop-ref-user-err.js
new file mode 100644
index 0000000000..bca0379d3c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-prop-ref-user-err.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-put-prop-ref-user-err.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: Any error raised as a result of setting the value should be forwarded to the runtime. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x = {
+ set y(val) {
+ throw new Test262Error();
+ }
+};
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([x.y] of [[23]]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-prop-ref.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-prop-ref.js
new file mode 100644
index 0000000000..fabda343d2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-prop-ref.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-put-prop-ref.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: The DestructuringAssignmentTarget of an AssignmentElement may be a PropertyReference. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x = {};
+
+var counter = 0;
+
+for ([x.y] of [[4]]) {
+ assert.sameValue(x.y, 4);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-unresolvable-no-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-unresolvable-no-strict.js
new file mode 100644
index 0000000000..76ec86c3a4
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-unresolvable-no-strict.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-put-unresolvable-no-strict.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Outside of strict mode, if the the assignment target is an unresolvable reference, a new `var` binding should be created in the environment record. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, noStrict]
+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.
+ [...]
+---*/
+{
+
+var counter = 0;
+
+for ([ unresolvable ] of [[]]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+}
+
+assert.sameValue(unresolvable, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-unresolvable-strict-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-unresolvable-strict-strict.js
new file mode 100644
index 0000000000..7a29183272
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-put-unresolvable-strict-strict.js
@@ -0,0 +1,40 @@
+'use strict';
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-put-unresolvable-strict.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: In strict mode, if the the assignment target is an unresolvable reference, a ReferenceError should be thrown. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, onlyStrict]
+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.
+ [...]
+---*/
+
+var counter = 0;
+
+assert.throws(ReferenceError, function() {
+ for ([ unresolvable ] of [[]]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-target-identifier.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-target-identifier.js
new file mode 100644
index 0000000000..dabe6c34d9
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-target-identifier.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-target-identifier.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Identifiers that appear as the DestructuringAssignmentTarget in an AssignmentElement should take on the iterated value corresponding to their position in the ArrayAssignmentPattern. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x, y, z;
+
+var counter = 0;
+
+for ([x, y, z] of [[1, 2, 3]]) {
+ assert.sameValue(x, 1);
+ assert.sameValue(y, 2);
+ assert.sameValue(z, 3);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-target-simple-no-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-target-simple-no-strict.js
new file mode 100644
index 0000000000..e046d2cfb0
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-target-simple-no-strict.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-target-simple-no-strict.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Identifiers that appear as the DestructuringAssignmentTarget in an AssignmentElement should take on the iterated value corresponding to their position in the ArrayAssignmentPattern. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, noStrict]
+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.
+ [...]
+---*/
+var argument, eval;
+
+var counter = 0;
+
+for ([arguments, eval] of [[2, 3]]) {
+ assert.sameValue(arguments, 2);
+ assert.sameValue(eval, 3);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-target-simple-strict-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-target-simple-strict-strict.js
new file mode 100644
index 0000000000..344718e293
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.template
+/*---
+description: It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is false. (For..of 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] of [[]]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-target-yield-expr.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-target-yield-expr.js
new file mode 100644
index 0000000000..253ebe13de
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-target-yield-expr.js
@@ -0,0 +1,56 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-target-yield-expr.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When a `yield` token appears within the DestructuringAssignmentTarget of an AssignmentElement within a generator function body, it behaves as a YieldExpression. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var value = [33];
+var x = {};
+var iterationResult, iter;
+
+iter = (function*() {
+
+var counter = 0;
+
+for ([ x[yield] ] of [[33]]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+}());
+
+iterationResult = iter.next();
+
+assert.sameValue(iterationResult.value, undefined);
+assert.sameValue(iterationResult.done, false);
+assert.sameValue(x.prop, undefined);
+
+iterationResult = iter.next('prop');
+
+assert.sameValue(iterationResult.value, undefined);
+assert.sameValue(iterationResult.done, true);
+assert.sameValue(x.prop, 33);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-target-yield-invalid-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-target-yield-invalid-strict.js
new file mode 100644
index 0000000000..a39b7cc37a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.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..of 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] ] of [[]]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-target-yield-valid.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-target-yield-valid.js
new file mode 100644
index 0000000000..779f769d75
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-target-yield-valid.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-target-yield-valid.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When a `yield` token appears within the DestructuringAssignmentTarget of an AssignmentElement outside of a generator function body, it behaves as an IdentifierReference. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, noStrict]
+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.
+ [...]
+---*/
+var yield = 'prop';
+var x = {};
+
+var counter = 0;
+
+for ([ x[yield] ] of [[33]]) {
+ assert.sameValue(x.prop, 33);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-elision-iter-abpt.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-elision-iter-abpt.js
new file mode 100644
index 0000000000..209a650414
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-elision-iter-abpt.js
@@ -0,0 +1,80 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-trlg-iter-elision-iter-abpt.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: Abrupt completion returned during evaluation of elision (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern :
+ [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+ [...]
+ 6. If Elision is present, then
+ a. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of Elision with
+ iteratorRecord as the argument.
+ b. If status is an abrupt completion, then
+ i. If iteratorRecord.[[done]] is false, return
+ IteratorClose(iterator, status).
+ ii. Return Completion(status).
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var x;
+var iterator = {
+ next: function() {
+ nextCount += 1;
+
+ if (nextCount === 2) {
+ throw new Test262Error();
+ }
+
+ // Set an upper-bound to limit unnecessary iteration in non-conformant
+ // implementations
+ return { done: nextCount > 10 };
+ },
+ return: function() {
+ returnCount += 1;
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([ x , , ] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+assert.sameValue(nextCount, 2);
+assert.sameValue(returnCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-elision-iter-nrml-close-err.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-elision-iter-nrml-close-err.js
new file mode 100644
index 0000000000..f43fbcfa38
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-elision-iter-nrml-close-err.js
@@ -0,0 +1,76 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-trlg-iter-elision-iter-nrml-close-err.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: Abrupt completion returned from IteratorClose (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern :
+ [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+ [...]
+ 6. If Elision is present, then
+ a. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of Elision with
+ iteratorRecord as the argument.
+ b. If status is an abrupt completion, then
+ [...]
+ 8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ status).
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var x;
+var iterator = {
+ next: function() {
+ nextCount += 1;
+
+ // Set an upper-bound to limit unnecessary iteration in non-conformant
+ // implementations
+ return { done: nextCount > 10 };
+ },
+ return: function() {
+ returnCount += 1;
+ throw new Test262Error();
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([ x , , ] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+assert.sameValue(nextCount, 2);
+assert.sameValue(returnCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-elision-iter-nrml-close-null.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-elision-iter-nrml-close-null.js
new file mode 100644
index 0000000000..c55e73a43b
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-elision-iter-nrml-close-null.js
@@ -0,0 +1,79 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-trlg-iter-elision-iter-nrml-close-null.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: IteratorClose throws a TypeError when `return` returns a non-Object value (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern :
+ [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+ [...]
+ 6. If Elision is present, then
+ a. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of Elision with
+ iteratorRecord as the argument.
+ b. If status is an abrupt completion, then
+ [...]
+ 8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ status).
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ 7. If completion.[[type]] is throw, return Completion(completion).
+ 8. If innerResult.[[type]] is throw, return Completion(innerResult).
+ 9. If Type(innerResult.[[value]]) is not Object, throw a TypeError
+ exception.
+
+---*/
+var iterable = {};
+var x;
+var nextCount = 0;
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ // Set an upper-bound to limit unnecessary iteration in non-conformant
+ // implementations
+ return { done: nextCount > 10 };
+ },
+ return: function() {
+ return null;
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ([ x , , ] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-elision-iter-nrml-close-skip.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-elision-iter-nrml-close-skip.js
new file mode 100644
index 0000000000..9894c4ce57
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-elision-iter-nrml-close-skip.js
@@ -0,0 +1,70 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-trlg-iter-elision-iter-nrml-close-skip.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: IteratorClose not invoked when elision exhausts the iterator (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern :
+ [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+ [...]
+ 6. If Elision is present, then
+ a. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of Elision with
+ iteratorRecord as the argument.
+ b. If status is an abrupt completion, then
+ [...]
+ 8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ status).
+ 9. Return Completion(status).
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var x;
+var iterator = {
+ next: function() {
+ nextCount += 1;
+
+ return { done: nextCount > 1 };
+ },
+ return: function() {
+ returnCount += 1;
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+for ([ x , , ] of [iterable]) {
+ assert.sameValue(nextCount, 2);
+ assert.sameValue(returnCount, 0);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-elision-iter-nrml-close.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-elision-iter-nrml-close.js
new file mode 100644
index 0000000000..50f94cba56
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-elision-iter-nrml-close.js
@@ -0,0 +1,85 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-trlg-iter-elision-iter-nrml-close.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: IteratorClose invoked when elision does not exhaust the iterator (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern :
+ [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+ [...]
+ 6. If Elision is present, then
+ a. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of Elision with
+ iteratorRecord as the argument.
+ b. If status is an abrupt completion, then
+ [...]
+ 8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ status).
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ [...]
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var thisValue = null;
+var args = null;
+var iterable = {};
+var x;
+var iterator = {
+ next: function() {
+ nextCount += 1;
+
+ // Set an upper-bound to limit unnecessary iteration in non-conformant
+ // implementations
+ return { done: nextCount > 10 };
+ },
+ return: function() {
+ returnCount += 1;
+ thisValue = this;
+ args = arguments;
+ return {};
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+for ([ x , , ] of [iterable]) {
+ assert.sameValue(nextCount, 2);
+ assert.sameValue(returnCount, 1);
+ assert.sameValue(thisValue, iterator, 'correct `this` value');
+ assert(!!args, 'arguments object provided');
+ assert.sameValue(args.length, 0, 'zero arguments specified');
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-get-err.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-get-err.js
new file mode 100644
index 0000000000..eb9e0a6f16
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-get-err.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-trlg-iter-get-err.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: Abrupt completion returned from GetIterator (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern :
+ [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+ 1. Let iterator be GetIterator(value).
+ 2. ReturnIfAbrupt(iterator).
+
+---*/
+var iterable = {};
+iterable[Symbol.iterator] = function() {
+ throw new Test262Error();
+};
+var x;
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([ x , ] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-nrml-close-err.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-nrml-close-err.js
new file mode 100644
index 0000000000..d825c94adf
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-nrml-close-err.js
@@ -0,0 +1,76 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-trlg-iter-list-nrml-close-err.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: Abrupt completion returned from IteratorClose (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern :
+ [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+ [...]
+ 3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
+ 4. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
+ iteratorRecord as the argument.
+ 5. If status is an abrupt completion, then
+ a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ status).
+ b. Return Completion(status).
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var thrower = function() {
+ throw new Test262Error();
+};
+var x;
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ return { done: nextCount > 10 };
+ },
+ return: function() {
+ returnCount += 1;
+ throw new Test262Error();
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([ x , ] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-nrml-close-null.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-nrml-close-null.js
new file mode 100644
index 0000000000..2e1ac4dc2f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-nrml-close-null.js
@@ -0,0 +1,79 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-trlg-iter-list-nrml-close-null.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: IteratorClose throws a TypeError when `return` returns a non-Object value (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern :
+ [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+ [...]
+ 3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
+ 4. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
+ iteratorRecord as the argument.
+ 5. If status is an abrupt completion, then
+ a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ status).
+ b. Return Completion(status).
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ 7. If completion.[[type]] is throw, return Completion(completion).
+ 8. If innerResult.[[type]] is throw, return Completion(innerResult).
+ 9. If Type(innerResult.[[value]]) is not Object, throw a TypeError
+ exception.
+
+---*/
+var iterable = {};
+var x;
+var nextCount = 0;
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ // Set an upper-bound to limit unnecessary iteration in non-conformant
+ // implementations
+ return { done: nextCount > 10 };
+ },
+ return: function() {
+ return null;
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ([ x , ] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-nrml-close-skip.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-nrml-close-skip.js
new file mode 100644
index 0000000000..f8b8c96b8b
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-nrml-close-skip.js
@@ -0,0 +1,71 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-trlg-iter-list-nrml-close-skip.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: IteratorClose is not invoked when evaluation of AssignmentElementList exhausts the iterator (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern :
+ [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+ [...]
+ 3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
+ 4. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
+ iteratorRecord as the argument.
+ 5. If status is an abrupt completion, then
+ a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ status).
+ b. Return Completion(status).
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var thrower = function() {
+ throw new Test262Error();
+};
+var x;
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ return { done: true };
+ },
+ return: function() {
+ returnCount += 1;
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+for ([ x , ] of [iterable]) {
+ assert.sameValue(nextCount, 1);
+ assert.sameValue(returnCount, 0);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-nrml-close.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-nrml-close.js
new file mode 100644
index 0000000000..8b279ded51
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-nrml-close.js
@@ -0,0 +1,84 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-trlg-iter-list-nrml-close.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: IteratorClose is invoked when evaluation of AssignmentElementList completes without exhausting the iterator (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern :
+ [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+ [...]
+ 3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
+ 4. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
+ iteratorRecord as the argument.
+ 5. If status is an abrupt completion, then
+ a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ status).
+ b. Return Completion(status).
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ [...]
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var thisValue = null;
+var args = null;
+var iterable = {};
+var x;
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ // Set an upper-bound to limit unnecessary iteration in non-conformant
+ // implementations
+ return { done: nextCount > 10 };
+ },
+ return: function() {
+ returnCount += 1;
+ thisValue = this;
+ args = arguments;
+ return {};
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+for ([ x , ] of [iterable]) {
+ assert.sameValue(nextCount, 1);
+ assert.sameValue(returnCount, 1);
+ assert.sameValue(thisValue, iterator, 'correct `this` value');
+ assert(!!args, 'arguments object provided');
+ assert.sameValue(args.length, 0, 'zero arguments specified');
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-rtrn-close-err.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-rtrn-close-err.js
new file mode 100644
index 0000000000..02520bfd06
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-rtrn-close-err.js
@@ -0,0 +1,91 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-trlg-iter-list-rtrn-close-err.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: IteratorClose is invoked when evaluation of AssignmentElementList returns a "return" completion and the iterator has not been marked as "done" (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, generators, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern :
+ [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+ [...]
+ 3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
+ 4. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
+ iteratorRecord as the argument.
+ 5. If status is an abrupt completion, then
+ a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ status).
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ 7. If completion.[[type]] is throw, return Completion(completion).
+ 8. If innerResult.[[type]] is throw, return Completion(innerResult).
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var unreachable = 0;
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ return {done: false, value: undefined};
+ },
+ return: function() {
+ returnCount += 1;
+
+ throw new Test262Error();
+ }
+};
+var iterable = {};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+function* g() {
+
+var counter = 0;
+
+for ([ {} = yield , ] of [iterable]) {
+ unreachable += 1;
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+}
+
+var iter = g();
+iter.next();
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
+assert.throws(Test262Error, function() {
+ iter.return();
+});
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 1);
+assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-rtrn-close-null.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-rtrn-close-null.js
new file mode 100644
index 0000000000..3ecd873557
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-rtrn-close-null.js
@@ -0,0 +1,91 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-trlg-iter-list-rtrn-close-null.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: IteratorClose throws a TypeError when `return` returns a non-Object value (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, generators, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern :
+ [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+ [...]
+ 3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
+ 4. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
+ iteratorRecord as the argument.
+ 5. If status is an abrupt completion, then
+ a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ status).
+ b. Return Completion(status).
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ 7. If completion.[[type]] is throw, return Completion(completion).
+ 8. If innerResult.[[type]] is throw, return Completion(innerResult).
+ 9. If Type(innerResult.[[value]]) is not Object, throw a TypeError
+ exception.
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ return {done: false, value: undefined};
+ },
+ return: function() {
+ returnCount += 1;
+ return null;
+ }
+};
+var iterable = {};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+function* g() {
+
+var counter = 0;
+
+for ([ {} = yield , ] of [iterable]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+}
+
+var iter = g();
+iter.next();
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
+assert.throws(TypeError, function() {
+ iter.return();
+});
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-rtrn-close.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-rtrn-close.js
new file mode 100644
index 0000000000..09c39d4e3a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-rtrn-close.js
@@ -0,0 +1,102 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-trlg-iter-list-rtrn-close.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: IteratorClose is invoked when evaluation of AssignmentElementList returns a "return" completion and the iterator has not been marked as "done" (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, generators, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern :
+ [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+ [...]
+ 3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
+ 4. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
+ iteratorRecord as the argument.
+ 5. If status is an abrupt completion, then
+ a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ status).
+ b. Return Completion(status).
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ 7. If completion.[[type]] is throw, return Completion(completion).
+ 8. If innerResult.[[type]] is throw, return Completion(innerResult).
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var unreachable = 0;
+var thisValue = null;
+var args = null;
+var iterable = {};
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ return {done: false, value: undefined};
+ },
+ return: function() {
+ returnCount += 1;
+ thisValue = this;
+ args = arguments;
+ return {};
+ }
+};
+var iter, result;
+
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+function* g() {
+
+var counter = 0;
+
+for ([ {} = yield , ] of [iterable]) {
+ unreachable += 1;
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+};
+
+iter = g();
+iter.next();
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
+
+result = iter.return(888);
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 1);
+assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
+assert.sameValue(result.value, 888);
+assert(result.done, 'Iterator correctly closed');
+assert.sameValue(thisValue, iterator, 'correct `this` value');
+assert(!!args, 'arguments object provided');
+assert.sameValue(args.length, 0, 'zero arguments specified');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-thrw-close-err.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-thrw-close-err.js
new file mode 100644
index 0000000000..f7932463fb
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-thrw-close-err.js
@@ -0,0 +1,84 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-trlg-iter-list-thrw-close-err.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: IteratorClose is invoked when evaluation of AssignmentElementList returns a "throw" completion and the iterator has not been marked as "done" (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern :
+ [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+ [...]
+ 3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
+ 4. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
+ iteratorRecord as the argument.
+ 5. If status is an abrupt completion, then
+ a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ status).
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 7. If completion.[[type]] is throw, return Completion(completion).
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var thrower = function() {
+ throw new Test262Error();
+};
+function ReturnError() {}
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ return { done: true };
+ },
+ return: function() {
+ returnCount += 1;
+
+ // This value should be discarded.
+ throw new ReturnError();
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([ {}[thrower()] , ] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+
+assert.sameValue(nextCount, 0);
+assert.sameValue(returnCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-thrw-close-skip.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-thrw-close-skip.js
new file mode 100644
index 0000000000..6091d997bc
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-thrw-close-skip.js
@@ -0,0 +1,75 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-trlg-iter-list-thrw-close-skip.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: IteratorClose is not invoked when evaluation of AssignmentElementList returns an abrupt completion and the iterator has been marked as "done" (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern :
+ [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+ [...]
+ 3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
+ 4. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
+ iteratorRecord as the argument.
+ 5. If status is an abrupt completion, then
+ a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ status).
+ b. Return Completion(status).
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var thrower = function() {
+ throw new Test262Error();
+};
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ throw new Test262Error();
+ },
+ return: function() {
+ returnCount += 1;
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+var x;
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([ x , ] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-thrw-close.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-thrw-close.js
new file mode 100644
index 0000000000..ee99d2439e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-list-thrw-close.js
@@ -0,0 +1,87 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-trlg-iter-list-thrw-close.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: IteratorClose is invoked when evaluation of AssignmentElementList returns a "throw" completion and the iterator has not been marked as "done" (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern :
+ [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+ [...]
+ 3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
+ 4. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
+ iteratorRecord as the argument.
+ 5. If status is an abrupt completion, then
+ a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ status).
+ b. Return Completion(status).
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ [...]
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var thisValue = null;
+var args = null;
+var iterable = {};
+var thrower = function() {
+ throw new Test262Error();
+};
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ return { done: true };
+ },
+ return: function() {
+ returnCount += 1;
+ thisValue = this;
+ args = arguments;
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([ {}[thrower()] , ] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+assert.sameValue(nextCount, 0);
+assert.sameValue(returnCount, 1);
+assert.sameValue(thisValue, iterator, 'correct `this` value');
+assert(!!args, 'arguments object provided');
+assert.sameValue(args.length, 0, 'zero arguments specified');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-nrml-close-skip.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-nrml-close-skip.js
new file mode 100644
index 0000000000..d14e6f9d3e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-nrml-close-skip.js
@@ -0,0 +1,71 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-trlg-iter-rest-nrml-close-skip.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: IteratorClose is not called when rest element evaluation has exhausted the iterator (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern :
+ [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+ [...]
+ 7. If AssignmentRestElement is present, then
+ a. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentRestElement
+ with iteratorRecord as the argument.
+ 8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ status).
+ 9. Return Completion(status).
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var x, y;
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ return { value: nextCount, done: nextCount > 1 };
+ },
+ return: function() {
+ returnCount += 1;
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+for ([ x , ...y ] of [iterable]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+assert.sameValue(nextCount, 2, 'nextCount');
+assert.sameValue(returnCount, 0, 'returnCount');
+assert.sameValue(x, 1, 'x');
+assert.sameValue(y.length, 0, 'y.length');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-rtrn-close-err.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-rtrn-close-err.js
new file mode 100644
index 0000000000..ea6f727c9f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-rtrn-close-err.js
@@ -0,0 +1,93 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-trlg-iter-rest-rtrn-close-err.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: IteratorClose is called when AssignmentRestEvaluation produces a "return" completion due to reference evaluation (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, generators, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern :
+ [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+ [...]
+ 7. If AssignmentRestElement is present, then
+ a. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentRestElement
+ with iteratorRecord as the argument.
+ 8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ status).
+ 9. Return Completion(status).
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ 7. If completion.[[type]] is throw, return Completion(completion).
+ 8. If innerResult.[[type]] is throw, return Completion(innerResult).
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var unreachable = 0;
+var x;
+var iterable = {};
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ // Set an upper-bound to limit unnecessary iteration in non-conformant
+ // implementations
+ return { done: nextCount > 10 };
+ },
+ return: function() {
+ returnCount += 1;
+
+ throw new Test262Error();
+ }
+};
+var iter;
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+function* g() {
+
+var counter = 0;
+
+for ([ x , ...{}[yield] ] of [iterable]) {
+ unreachable += 1;
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+}
+
+iter = g();
+iter.next();
+
+assert.throws(Test262Error, function() {
+ iter.return();
+});
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 1);
+assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-rtrn-close-null.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-rtrn-close-null.js
new file mode 100644
index 0000000000..95e723e06b
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-rtrn-close-null.js
@@ -0,0 +1,88 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-trlg-iter-rest-rtrn-close-null.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: IteratorClose throws a TypeError when `return` returns a non-Object value (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, generators, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern :
+ [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+ [...]
+ 7. If AssignmentRestElement is present, then
+ a. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentRestElement
+ with iteratorRecord as the argument.
+ 8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ status).
+ 9. Return Completion(status).
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ 7. If completion.[[type]] is throw, return Completion(completion).
+ 8. If innerResult.[[type]] is throw, return Completion(innerResult).
+
+---*/
+var nextCount = 0;
+var iterable = {};
+var x;
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ // Set an upper-bound to limit unnecessary iteration in non-conformant
+ // implementations
+ return { done: nextCount > 10 };
+ },
+ return: function() {
+ return null;
+ }
+};
+var iter;
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+function* g() {
+
+var counter = 0;
+
+for ([ x , ...{}[yield] ] of [iterable]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+}
+
+iter = g();
+iter.next();
+
+assert.throws(TypeError, function() {
+ iter.return();
+});
+
+assert.sameValue(nextCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-rtrn-close.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-rtrn-close.js
new file mode 100644
index 0000000000..20a278c1ca
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-rtrn-close.js
@@ -0,0 +1,99 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-trlg-iter-rest-rtrn-close.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: IteratorClose is called when AssignmentRestEvaluation produces a "return" completion due to reference evaluation (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, generators, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern :
+ [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+ [...]
+ 7. If AssignmentRestElement is present, then
+ a. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentRestElement
+ with iteratorRecord as the argument.
+ 8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ status).
+ 9. Return Completion(status).
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ 7. If completion.[[type]] is throw, return Completion(completion).
+ 8. If innerResult.[[type]] is throw, return Completion(innerResult).
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var unreachable = 0;
+var thisValue = null;
+var args = null;
+var iterable = {};
+var x;
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ // Set an upper-bound to limit unnecessary iteration in non-conformant
+ // implementations
+ return { done: nextCount > 10 };
+ },
+ return: function() {
+ returnCount += 1;
+ thisValue = this;
+ args = arguments;
+ return {};
+ }
+};
+var iter, result;
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+function* g() {
+
+var counter = 0;
+
+for ([ x , ...{}[yield] ] of [iterable]) {
+ unreachable += 1;
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+}
+
+iter = g();
+iter.next();
+result = iter.return(999);
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 1);
+assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
+assert.sameValue(result.value, 999);
+assert(result.done, 'Iterator correctly closed');
+assert.sameValue(thisValue, iterator, 'correct `this` value');
+assert(!!args, 'arguments object provided');
+assert.sameValue(args.length, 0, 'zero arguments specified');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-thrw-close-err.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-thrw-close-err.js
new file mode 100644
index 0000000000..7e669658ba
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-thrw-close-err.js
@@ -0,0 +1,85 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-trlg-iter-rest-thrw-close-err.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: IteratorClose is called when AssignmentRestEvaluation produces a "throw" completion due to reference evaluation (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern :
+ [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+ [...]
+ 7. If AssignmentRestElement is present, then
+ a. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentRestElement
+ with iteratorRecord as the argument.
+ 8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ status).
+ 9. Return Completion(status).
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 7. If completion.[[type]] is throw, return Completion(completion)
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var x;
+function ReturnError() {}
+var iterable = {};
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ // Set an upper-bound to limit unnecessary iteration in non-conformant
+ // implementations
+ return { done: nextCount > 10 };
+ },
+ return: function() {
+ returnCount += 1;
+
+ // This value should be discarded.
+ throw new ReturnError();
+ }
+};
+var thrower = function() {
+ throw new Test262Error();
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([ x , ...{}[thrower()] ] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-thrw-close-skip.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-thrw-close-skip.js
new file mode 100644
index 0000000000..2b210e7b00
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-thrw-close-skip.js
@@ -0,0 +1,78 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-trlg-iter-rest-thrw-close-skip.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: Abrupt completion returned during iteration for rest element (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern :
+ [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+ [...]
+ 7. If AssignmentRestElement is present, then
+ a. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentRestElement
+ with iteratorRecord as the argument.
+ 8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ status).
+ 9. Return Completion(status).
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var x;
+var iterator = {
+ next: function() {
+ nextCount += 1;
+
+ if (nextCount === 2) {
+ throw new Test262Error();
+ }
+
+ // Set an upper-bound to limit unnecessary iteration in non-conformant
+ // implementations
+ return { done: nextCount > 10 };
+ },
+ return: function() {
+ returnCount += 1;
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([ x , ...x ] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+assert.sameValue(nextCount, 2);
+assert.sameValue(returnCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-thrw-close.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-thrw-close.js
new file mode 100644
index 0000000000..62a5eea52c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elem-trlg-iter-rest-thrw-close.js
@@ -0,0 +1,89 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-trlg-iter-rest-thrw-close.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: IteratorClose is called when AssignmentRestEvaluation produces a "throw" completion due to reference evaluation (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern :
+ [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+ [...]
+ 7. If AssignmentRestElement is present, then
+ a. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentRestElement
+ with iteratorRecord as the argument.
+ 8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ status).
+ 9. Return Completion(status).
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ [...]
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var thisValue = null;
+var args = null;
+var iterable = {};
+var x;
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ // Set an upper-bound to limit unnecessary iteration in non-conformant
+ // implementations
+ return { done: nextCount > 10 };
+ },
+ return: function() {
+ returnCount += 1;
+ thisValue = this;
+ args = arguments;
+ }
+};
+var thrower = function() {
+ throw new Test262Error();
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([ x , ...{}[thrower()] ] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 1);
+assert.sameValue(thisValue, iterator, 'correct `this` value');
+assert(!!args, 'arguments object provided');
+assert.sameValue(args.length, 0, 'zero arguments specified');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elision-iter-abpt.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elision-iter-abpt.js
new file mode 100644
index 0000000000..ec3c4fdb92
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elision-iter-abpt.js
@@ -0,0 +1,66 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elision-iter-abpt.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: IteratorClose is not called when iteration produces an abrupt completion (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ Elision ]
+
+ 1. Let iterator be GetIterator(value).
+ [...]
+ 5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+ [...]
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ throw new Test262Error();
+ },
+ return: function() {
+ returnCount += 1;
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([ , ] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elision-iter-get-err.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elision-iter-get-err.js
new file mode 100644
index 0000000000..1c4e3e0c27
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elision-iter-get-err.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elision-iter-get-err.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: Abrupt completion returned from GetIterator (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ Elision ]
+
+ 1. Let iterator be GetIterator(value).
+ 2. ReturnIfAbrupt(iterator).
+
+---*/
+var iterable = {};
+iterable[Symbol.iterator] = function() {
+ throw new Test262Error();
+};
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([ , ] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elision-iter-nrml-close-err.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elision-iter-nrml-close-err.js
new file mode 100644
index 0000000000..10c4ed8604
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elision-iter-nrml-close-err.js
@@ -0,0 +1,69 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elision-iter-nrml-close-err.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: Abrupt completion returned from IteratorClose (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ Elision ]
+
+ 1. Let iterator be GetIterator(value).
+ [...]
+ 5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+ 6. Return result.
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ // Set an upper-bound to limit unnecessary iteration in non-conformant
+ // implementations
+ return { done: nextCount > 10 };
+ },
+ return: function() {
+ returnCount += 1;
+ throw new Test262Error();
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([ , ] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elision-iter-nrml-close-null.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elision-iter-nrml-close-null.js
new file mode 100644
index 0000000000..80d05752b2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elision-iter-nrml-close-null.js
@@ -0,0 +1,73 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elision-iter-nrml-close-null.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: IteratorClose throws a TypeError when `return` returns a non-Object value (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ Elision ]
+
+ 1. Let iterator be GetIterator(value).
+ [...]
+ 5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+ [...]
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ 7. If completion.[[type]] is throw, return Completion(completion).
+ 8. If innerResult.[[type]] is throw, return Completion(innerResult).
+ 9. If Type(innerResult.[[value]]) is not Object, throw a TypeError
+ exception.
+
+---*/
+var iterable = {};
+var nextCount = 0;
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ // Set an upper-bound to limit unnecessary iteration in non-conformant
+ // implementations
+ return { done: nextCount > 10 };
+ },
+ return: function() {
+ return null;
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ([ , ] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elision-iter-nrml-close-skip.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elision-iter-nrml-close-skip.js
new file mode 100644
index 0000000000..aa8d78b8fd
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elision-iter-nrml-close-skip.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elision-iter-nrml-close-skip.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: IteratorClose is not called when iteration has exhausted the iterator (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ Elision ]
+
+ 1. Let iterator be GetIterator(value).
+ [...]
+ 5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+ [...]
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ return { done: true };
+ },
+ return: function() {
+ returnCount += 1;
+ return {};
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+for ([ , ] of [iterable]) {
+ assert.sameValue(nextCount, 1);
+ assert.sameValue(returnCount, 0);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elision-iter-nrml-close.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elision-iter-nrml-close.js
new file mode 100644
index 0000000000..d49c8e3f12
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elision-iter-nrml-close.js
@@ -0,0 +1,78 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elision-iter-nrml-close.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: IteratorClose is called when assignment evaluation has not exhausted the iterator (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ Elision ]
+
+ 1. Let iterator be GetIterator(value).
+ [...]
+ 5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+ [...]
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ [...]
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var thisValue = null;
+var args = null;
+var iterable = {};
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ // Set an upper-bound to limit unnecessary iteration in non-conformant
+ // implementations
+ return { done: nextCount > 10 };
+ },
+ return: function() {
+ returnCount += 1;
+ thisValue = this;
+ args = arguments;
+ return {};
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+for ([ , ] of [iterable]) {
+ assert.sameValue(nextCount, 1);
+ assert.sameValue(returnCount, 1);
+ assert.sameValue(thisValue, iterator, 'correct `this` value');
+ assert(!!args, 'arguments object provided');
+ assert.sameValue(args.length, 0, 'zero arguments specified');
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-array.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-array.js
new file mode 100644
index 0000000000..928f7371b1
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-array.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elision-val-array.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: An ArrayAssignmentPattern containing only Elisions requires iterable values (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+
+var counter = 0;
+
+for ([,] of [[]]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-bool.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-bool.js
new file mode 100644
index 0000000000..d0ac48f268
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-bool.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elision-val-bool.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: An ArrayAssignmentPattern containing only Elisions requires iterable values and throws for boolean values. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ([,] of [true]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-null.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-null.js
new file mode 100644
index 0000000000..cc9f581817
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-null.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elision-val-null.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: An ArrayAssignmentPattern containing only Elisions requires iterable values and throws for `null`. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ([,] of [null]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-num.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-num.js
new file mode 100644
index 0000000000..67b15faa51
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-num.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elision-val-num.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: An ArrayAssignmentPattern containing only Elisions requires iterable values and throws for number values. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ([,] of [1]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-string.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-string.js
new file mode 100644
index 0000000000..7e3eb227cb
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-string.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elision-val-string.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: An ArrayAssignmentPattern containing only Elisions requires iterable values (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+
+var counter = 0;
+
+for ([,] of ['string literal']) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-symbol.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-symbol.js
new file mode 100644
index 0000000000..5e108f191e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-symbol.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elision-val-symbol.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: An ArrayAssignmentPattern containing only Elisions requires iterable values and throws for symbol values. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var s = Symbol();
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ([,] of [s]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-undef.js b/js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-undef.js
new file mode 100644
index 0000000000..34f979d148
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-elision-val-undef.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elision-val-undef.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: An ArrayAssignmentPattern containing only Elisions requires iterable values and throws for `undefined`. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ([,] of [undefined]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-empty-iter-close-err.js b/js/src/tests/test262/language/statements/for-of/dstr/array-empty-iter-close-err.js
new file mode 100644
index 0000000000..1de55b5d7d
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-empty-iter-close-err.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-empty-iter-close-err.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: Abrupt completion returned from IteratorClose (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ ]
+
+ 1. Let iterator be GetIterator(value).
+ 2. ReturnIfAbrupt(iterator).
+ 3. Return IteratorClose(iterator, NormalCompletion(empty)).
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ return { done: true };
+ },
+ return: function() {
+ returnCount += 1;
+ throw new Test262Error();
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+assert.sameValue(nextCount, 0);
+assert.sameValue(returnCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-empty-iter-close-null.js b/js/src/tests/test262/language/statements/for-of/dstr/array-empty-iter-close-null.js
new file mode 100644
index 0000000000..974e7ee66e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-empty-iter-close-null.js
@@ -0,0 +1,67 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-empty-iter-close-null.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: IteratorClose throws a TypeError when `return` returns a non-Object value (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ ]
+
+ 1. Let iterator be GetIterator(value).
+ 2. ReturnIfAbrupt(iterator).
+ 3. Return IteratorClose(iterator, NormalCompletion(empty)).
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ 7. If completion.[[type]] is throw, return Completion(completion).
+ 8. If innerResult.[[type]] is throw, return Completion(innerResult).
+ 9. If Type(innerResult.[[value]]) is not Object, throw a TypeError
+ exception.
+
+---*/
+var iterable = {};
+var iterator = {
+ next: function() {
+ return { done: true };
+ },
+ return: function() {
+ return null;
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ([] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-empty-iter-close.js b/js/src/tests/test262/language/statements/for-of/dstr/array-empty-iter-close.js
new file mode 100644
index 0000000000..cb2179bb78
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-empty-iter-close.js
@@ -0,0 +1,74 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-empty-iter-close.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Iterator is closed without iterating (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ ]
+
+ 1. Let iterator be GetIterator(value).
+ 2. ReturnIfAbrupt(iterator).
+ 3. Return IteratorClose(iterator, NormalCompletion(empty)).
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ [...]
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var thisValue = null;
+var args = null;
+var iterable = {};
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ return { done: true };
+ },
+ return: function() {
+ returnCount += 1;
+ thisValue = this;
+ args = arguments;
+ return {};
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+for ([] of [iterable]) {
+ assert.sameValue(nextCount, 0);
+ assert.sameValue(returnCount, 1);
+ assert.sameValue(thisValue, iterator, 'correct `this` value');
+ assert(!!args, 'arguments object provided');
+ assert.sameValue(args.length, 0, 'zero arguments specified');
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-empty-iter-get-err.js b/js/src/tests/test262/language/statements/for-of/dstr/array-empty-iter-get-err.js
new file mode 100644
index 0000000000..78b769aaff
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-empty-iter-get-err.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-empty-iter-get-err.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: Abrupt completion returned from GetIterator (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ ]
+
+ 1. Let iterator be GetIterator(value).
+ 2. ReturnIfAbrupt(iterator).
+
+---*/
+var iterable = {};
+iterable[Symbol.iterator] = function() {
+ throw new Test262Error();
+};
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-array.js b/js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-array.js
new file mode 100644
index 0000000000..35c4607eea
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-array.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-empty-val-array.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: An ArrayAssignmentPattern without an AssignmentElementList requires iterable values. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+
+var counter = 0;
+
+for ([] of [[]]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-bool.js b/js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-bool.js
new file mode 100644
index 0000000000..d214286a58
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-bool.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-empty-val-bool.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: An ArrayAssignmentPattern without an AssignmentElementList requires iterable values and throws for boolean values (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ([] of [true]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-null.js b/js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-null.js
new file mode 100644
index 0000000000..9b443df948
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-null.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-empty-val-null.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: An ArrayAssignmentPattern without an AssignmentElementList requires iterable values and throws for `null`. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ([] of [null]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-num.js b/js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-num.js
new file mode 100644
index 0000000000..810a70201d
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-num.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-empty-val-num.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: An ArrayAssignmentPattern without an AssignmentElementList requires iterable values and throws for number values. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ([] of [1]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-string.js b/js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-string.js
new file mode 100644
index 0000000000..42c37c37b3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-string.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-empty-val-string.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: An ArrayAssignmentPattern without an AssignmentElementList requires iterable values. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+
+var counter = 0;
+
+for ([] of ['string literal']) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-symbol.js b/js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-symbol.js
new file mode 100644
index 0000000000..10dbd8e691
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-symbol.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-empty-val-symbol.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: An ArrayAssignmentPattern without an AssignmentElementList requires iterable values and throws for Symbol values. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var s = Symbol();
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ([] of [s]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-undef.js b/js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-undef.js
new file mode 100644
index 0000000000..21bb4b5eb3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-empty-val-undef.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-empty-val-undef.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: An ArrayAssignmentPattern without an AssignmentElementList requires iterable values and throws for `undefined`. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ([] of [undefined]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-iteration.js b/js/src/tests/test262/language/statements/for-of/dstr/array-iteration.js
new file mode 100644
index 0000000000..3610f3a338
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-iteration.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-iteration.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Value iteration only proceeds for the number of elements in the ArrayAssignmentPattern. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var count = 0;
+var g = function*() {
+ count += 1;
+ yield;
+ count += 1;
+ yield;
+ count += 1;
+}
+
+var counter = 0;
+
+for ([,,] of [g()]) {
+ assert.sameValue(count, 2);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-after-element.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-after-element.js
new file mode 100644
index 0000000000..479d42ce9c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-after-element.js
@@ -0,0 +1,41 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-after-element.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: An AssignmentRestElement following an AssignmentElement consumes all remaining iterable values. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x, y;
+
+var counter = 0;
+
+for ([x, ...y] of [[1, 2, 3]]) {
+ assert.sameValue(x, 1);
+ assert.sameValue(y.length, 2);
+ assert.sameValue(y[0], 2);
+ assert.sameValue(y[1], 3);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-after-elision.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-after-elision.js
new file mode 100644
index 0000000000..12d68319a0
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-after-elision.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-after-elision.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: An AssignmentRestElement following an elision consumes all remaining iterable values. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+for ([, ...x] of [[1, 2, 3]]) {
+ assert.sameValue(x.length, 2);
+ assert.sameValue(x[0], 2);
+ assert.sameValue(x[1], 3);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-before-element.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-before-element.js
new file mode 100644
index 0000000000..4f85f4ed44
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.template
+/*---
+description: An AssignmentElement may not follow an AssignmentRestElement in an AssignmentElementList. (For..of 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] of [[]]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-before-elision.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-before-elision.js
new file mode 100644
index 0000000000..6c81944496
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.template
+/*---
+description: An elision may not follow an AssignmentRestElement in an AssignmentElementList. (For..of 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,] of [[]]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-before-rest.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-before-rest.js
new file mode 100644
index 0000000000..8898ee2dd1
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.template
+/*---
+description: An AssignmentRestElement may not follow another AssignmentRestElement in an AssignmentElementList. (For..of 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] of [[]]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-elision-invalid.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-elision-invalid.js
new file mode 100644
index 0000000000..69122c7ceb
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.template
+/*---
+description: ArrayAssignmentPattern may not include elisions following an AssignmentRestElement in a AssignmentElementList. (For..of 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,] of [[]]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-elision-iter-abpt.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-elision-iter-abpt.js
new file mode 100644
index 0000000000..78b9770c33
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-elision-iter-abpt.js
@@ -0,0 +1,71 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-elision-iter-abpt.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: IteratorClose is not called when assignment evaluation produces an abrupt completion (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+ [...]
+ 4. If Elision is present, then
+ a. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of Elision with
+ iteratorRecord as the argument.
+ b. If status is an abrupt completion, then
+ i. If iteratorRecord.[[done]] is false, return
+ IteratorClose(iterator, status).
+ ii. Return Completion(status).
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ throw new Test262Error();
+ },
+ return: function() {
+ returnCount += 1;
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+var x;
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([ , ...x] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-elision.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-elision.js
new file mode 100644
index 0000000000..50b9dc4d18
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-elision.js
@@ -0,0 +1,41 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-elision.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: ArrayAssignmentPattern may include elisions at any position preceding a AssignmentRestElement in a AssignmentElementList. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x, y;
+
+var counter = 0;
+
+for ([, , x, , ...y] of [[1, 2, 3, 4, 5, 6]]) {
+ assert.sameValue(x, 3);
+ assert.sameValue(y.length, 2);
+ assert.sameValue(y[0], 5);
+ assert.sameValue(y[1], 6);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-init.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-init.js
new file mode 100644
index 0000000000..f7181ff364
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.template
+/*---
+description: The AssignmentRestElement does not support an initializer. (For..of 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] of [[]]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-get-err.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-get-err.js
new file mode 100644
index 0000000000..b566e7b806
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-get-err.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-iter-get-err.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: Abrupt completion returned from GetIterator (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+ 1. Let iterator be GetIterator(value).
+ 2. ReturnIfAbrupt(iterator).
+
+---*/
+var iterable = {};
+var x;
+iterable[Symbol.iterator] = function() {
+ throw new Test262Error();
+};
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([...x] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-nrml-close-skip.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-nrml-close-skip.js
new file mode 100644
index 0000000000..497d477f7e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-nrml-close-skip.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-iter-nrml-close-skip.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: IteratorClose is not called when assignment evaluation has exhausted the iterator (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+ [...]
+ 5. Let result be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
+ iteratorRecord as the argument
+ 6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+ 7. Return result.
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var x;
+var iterable = {};
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ return { done: true };
+ },
+ return: function() {
+ returnCount += 1;
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+for ([ ...x ] of [iterable]) {
+ assert.sameValue(nextCount, 1);
+ assert.sameValue(returnCount, 0);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-rtrn-close-err.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-rtrn-close-err.js
new file mode 100644
index 0000000000..d35bfcfd0e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-rtrn-close-err.js
@@ -0,0 +1,88 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-iter-rtrn-close-err.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: IteratorClose is called when reference evaluation produces a "return" completion (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, generators, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+ [...]
+ 5. Let result be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
+ iteratorRecord as the argument
+ 6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+
+ AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
+
+ 1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an
+ ArrayLiteral, then
+ a. Let lref be the result of evaluating DestructuringAssignmentTarget.
+ b. ReturnIfAbrupt(lref).
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ 7. If completion.[[type]] is throw, return Completion(completion).
+ 8. If innerResult.[[type]] is throw, return Completion(innerResult).
+
+---*/
+var returnCount = 0;
+var unreachable = 0;
+var iterable = {};
+var iterator = {
+ return: function() {
+ returnCount += 1;
+
+ throw new Test262Error();
+ }
+};
+var iter;
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+function* g() {
+
+var counter = 0;
+
+for ([...{}[yield]] of [iterable]) {
+ unreachable += 1;
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+}
+
+iter = g();
+iter.next();
+assert.throws(Test262Error, function() {
+ iter.return();
+});
+
+assert.sameValue(returnCount, 1);
+assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-rtrn-close-null.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-rtrn-close-null.js
new file mode 100644
index 0000000000..9c6d19e9fe
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-rtrn-close-null.js
@@ -0,0 +1,88 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-iter-rtrn-close-null.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: IteratorClose throws a TypeError when `return` returns a non-Object value (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, generators, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+ [...]
+ 5. Let result be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
+ iteratorRecord as the argument
+ 6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+
+ AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
+
+ 1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an
+ ArrayLiteral, then
+ a. Let lref be the result of evaluating DestructuringAssignmentTarget.
+ b. ReturnIfAbrupt(lref).
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ [...]
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ 7. If completion.[[type]] is throw, return Completion(completion).
+ 8. If innerResult.[[type]] is throw, return Completion(innerResult).
+
+---*/
+var iterable = {};
+var iterator = {
+ return: function() {
+ return null;
+ }
+};
+var iter;
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+function* g() {
+
+var counter = 0;
+
+for ([...{}[yield]] of [iterable]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+}
+
+iter = g();
+iter.next();
+
+assert.throws(TypeError, function() {
+ iter.return();
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-rtrn-close.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-rtrn-close.js
new file mode 100644
index 0000000000..2d37e4bfe2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-rtrn-close.js
@@ -0,0 +1,103 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-iter-rtrn-close.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: IteratorClose is called when reference evaluation produces a "return" completion (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, generators, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+ [...]
+ 5. Let result be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
+ iteratorRecord as the argument
+ 6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+
+ AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
+
+ 1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an
+ ArrayLiteral, then
+ a. Let lref be the result of evaluating DestructuringAssignmentTarget.
+ b. ReturnIfAbrupt(lref).
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ [...]
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ 7. If completion.[[type]] is throw, return Completion(completion).
+ 8. If innerResult.[[type]] is throw, return Completion(innerResult).
+
+---*/
+var returnCount = 0;
+var unreachable = 0;
+var thisValue = null;
+var args = null;
+var iterable = {};
+var iterator = {
+ next() {
+ throw new Test262Error();
+ },
+ return: function() {
+ returnCount += 1;
+ thisValue = this;
+ args = arguments;
+ return {};
+ }
+};
+var iter, result;
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+function* g() {
+
+var counter = 0;
+
+for ([...{}[yield]] of [iterable]) {
+ unreachable += 1;
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+}
+
+iter = g();
+iter.next();
+result = iter.return(444);
+
+assert.sameValue(returnCount, 1);
+assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
+assert.sameValue(result.value, 444);
+assert(result.done, 'Iterator correctly closed');
+assert.sameValue(thisValue, iterator, 'correct `this` value');
+assert(!!args, 'arguments object provided');
+assert.sameValue(args.length, 0, 'zero arguments specified');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-thrw-close-err.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-thrw-close-err.js
new file mode 100644
index 0000000000..4d8a233e94
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-thrw-close-err.js
@@ -0,0 +1,85 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-iter-thrw-close-err.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: IteratorClose is called when reference evaluation produces a "throw" completion (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+ [...]
+ 5. Let result be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
+ iteratorRecord as the argument
+ 6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+
+ AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
+
+ 1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an
+ ArrayLiteral, then
+ a. Let lref be the result of evaluating DestructuringAssignmentTarget.
+ b. ReturnIfAbrupt(lref).
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var x;
+function ReturnError() {}
+var iterable = {};
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ // Set an upper-bound to limit unnecessary iteration in non-conformant
+ // implementations
+ return { done: nextCount > 10 };
+ },
+ return: function() {
+ returnCount += 1;
+
+ // This value should be discarded.
+ throw new ReturnError();
+ }
+};
+var thrower = function() {
+ throw new Test262Error();
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([...{}[thrower()]] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+assert.sameValue(nextCount, 0);
+assert.sameValue(returnCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-thrw-close-skip.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-thrw-close-skip.js
new file mode 100644
index 0000000000..b38d26b98d
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-thrw-close-skip.js
@@ -0,0 +1,68 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-iter-thrw-close-skip.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: IteratorClose is not called when iteration produces an abrupt completion (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+ [...]
+ 5. Let result be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
+ iteratorRecord as the argument
+ 6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var x;
+var iterable = {};
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ throw new Test262Error();
+ },
+ return: function() {
+ returnCount += 1;
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([...x] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-thrw-close.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-thrw-close.js
new file mode 100644
index 0000000000..8d50a51a9e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iter-thrw-close.js
@@ -0,0 +1,93 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-iter-thrw-close.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: IteratorClose is called when reference evaluation produces a "throw" completion (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+ [...]
+ 5. Let result be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
+ iteratorRecord as the argument
+ 6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+
+ AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
+
+ 1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an
+ ArrayLiteral, then
+ a. Let lref be the result of evaluating DestructuringAssignmentTarget.
+ b. ReturnIfAbrupt(lref).
+
+ 7.4.6 IteratorClose( iterator, completion )
+
+ [...]
+ 6. Let innerResult be Call(return, iterator, « »).
+ [...]
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var thisValue = null;
+var args = null;
+var x;
+var iterable = {};
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ // Set an upper-bound to limit unnecessary iteration in non-conformant
+ // implementations
+ return { done: nextCount > 10 };
+ },
+ return: function() {
+ returnCount += 1;
+ thisValue = this;
+ args = arguments;
+ }
+};
+var thrower = function() {
+ throw new Test262Error();
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([...{}[thrower()]] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+assert.sameValue(nextCount, 0);
+assert.sameValue(returnCount, 1);
+assert.sameValue(thisValue, iterator, 'correct `this` value');
+assert(!!args, 'arguments object provided');
+assert.sameValue(args.length, 0, 'zero arguments specified');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iteration.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iteration.js
new file mode 100644
index 0000000000..d72db7dfa4
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-iteration.js
@@ -0,0 +1,46 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-iteration.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: In the presense of an AssignmentRestElement, value iteration exhausts the iterable value; (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var count = 0;
+var g = function*() {
+ count += 1;
+ yield;
+ count += 1;
+ yield;
+ count += 1;
+}
+var x;
+
+var counter = 0;
+
+for ([...x] of [g()]) {
+ assert.sameValue(count, 3);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-lref-err.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-lref-err.js
new file mode 100644
index 0000000000..bbb495da20
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-lref-err.js
@@ -0,0 +1,77 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-lref-err.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: IteratorClose is called when reference evaluation produces an abrupt completion (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+ [...]
+ 5. Let result be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
+ iteratorRecord as the argument
+ 6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+
+ AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
+
+ 1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an
+ ArrayLiteral, then
+ a. Let lref be the result of evaluating DestructuringAssignmentTarget.
+ b. ReturnIfAbrupt(lref).
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ return { done: true };
+ },
+ return: function() {
+ returnCount += 1;
+ }
+};
+var thrower = function() {
+ throw new Test262Error();
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([...{}[thrower()]] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+assert.sameValue(nextCount, 0);
+assert.sameValue(returnCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-lref.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-lref.js
new file mode 100644
index 0000000000..88c55def71
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-lref.js
@@ -0,0 +1,74 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-lref.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Reference is evaluated during assignment (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+ [...]
+ 5. Let result be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
+ iteratorRecord as the argument
+ 6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+
+ AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
+
+ 1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an
+ ArrayLiteral, then
+ a. Let lref be the result of evaluating DestructuringAssignmentTarget.
+ b. ReturnIfAbrupt(lref).
+ [...]
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ return { done: true };
+ },
+ return: function() {
+ returnCount += 1;
+ }
+};
+var obj = {};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+for ([...obj['a' + 'b']] of [iterable]) {
+ assert.sameValue(nextCount, 1);
+ assert.sameValue(returnCount, 0);
+ assert(!!obj.ab);
+ assert.sameValue(obj.ab.length, 0);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-invalid.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-invalid.js
new file mode 100644
index 0000000000..755d5ddd22
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.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..of 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)]] of [[[]]]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-iter-thrw-close-skip.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-iter-thrw-close-skip.js
new file mode 100644
index 0000000000..cbe266ff9c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-iter-thrw-close-skip.js
@@ -0,0 +1,80 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-nested-array-iter-thrw-close-skip.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: IteratorClose is not called when nested array pattern evaluation produces an abrupt completion (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+ [...]
+ 5. Let result be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
+ iteratorRecord as the argument
+ 6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+
+ AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
+
+ [...]
+ 4. Repeat while iteratorRecord.[[done]] is false
+ [...]
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ [...]
+ 7. Return the result of performing DestructuringAssignmentEvaluation of
+ nestedAssignmentPattern with A as the argument.
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ return { done: true };
+ },
+ return: function() {
+ returnCount += 1;
+ }
+};
+var thrower = function() {
+ throw new Test262Error();
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([...[...{}[thrower()]]] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-null.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-null.js
new file mode 100644
index 0000000000..c19fe03c4e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-null.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-nested-array-null.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an array literal and the iterable emits `null` as the only value, an array with a single `null` element should be used as the value of the nested DestructuringAssignment. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x, y;
+
+var counter = 0;
+
+for ([...[x, y]] of [[null]]) {
+ assert.sameValue(x, null);
+ assert.sameValue(y, undefined);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-undefined-hole.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-undefined-hole.js
new file mode 100644
index 0000000000..e54d64285b
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-undefined-hole.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-nested-array-undefined-hole.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an array literal and the iterable is an array with a "hole", an array with a single `undefined` element should be used as the value of the nested DestructuringAssignment. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x = null;
+
+var counter = 0;
+
+for ([...[x]] of [[ , ]]) {
+ assert.sameValue(x, undefined);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-undefined-own.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-undefined-own.js
new file mode 100644
index 0000000000..d36db6c846
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-undefined-own.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-nested-array-undefined-own.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an array literal and the iterable emits `undefined` as the only value, an array with a single `undefined` element should be used as the value of the nested DestructuringAssignment. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x = null;
+
+var counter = 0;
+
+for ([...[x]] of [[undefined]]) {
+ assert.sameValue(x, undefined);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-undefined.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-undefined.js
new file mode 100644
index 0000000000..a9db7a0b79
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-undefined.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-nested-array-undefined.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an array literal and the iterable is emits no values, an empty array should be used as the value of the nested DestructuringAssignment. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x = null;
+
+var counter = 0;
+
+for ([...[x]] of [[]]) {
+ assert.sameValue(x, undefined);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-yield-expr.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-yield-expr.js
new file mode 100644
index 0000000000..ea7b1adfdd
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-yield-expr.js
@@ -0,0 +1,56 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-nested-array-yield-expr.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When a `yield` token appears within the DestructuringAssignmentTarget of a nested destructuring assignment and within a generator function body, it should behave as a YieldExpression. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var value = [86];
+var x = {};
+var iterationResult, iter;
+
+iter = (function*() {
+
+var counter = 0;
+
+for ([...[x[yield]]] of [[86]]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+}());
+
+iterationResult = iter.next();
+
+assert.sameValue(iterationResult.value, undefined);
+assert.sameValue(iterationResult.done, false);
+assert.sameValue(x.prop, undefined);
+
+iterationResult = iter.next('prop');
+
+assert.sameValue(iterationResult.value, undefined);
+assert.sameValue(iterationResult.done, true);
+assert.sameValue(x.prop, 86);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-yield-ident-invalid-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-yield-ident-invalid-strict.js
new file mode 100644
index 0000000000..fb2fb1e0d3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.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..of 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]]] of [[]]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-yield-ident-valid.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-yield-ident-valid.js
new file mode 100644
index 0000000000..47be4f44c6
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array-yield-ident-valid.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-nested-array-yield-ident-valid.case
+// - src/dstr-assignment/default/for-of.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..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, noStrict]
+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.
+ [...]
+---*/
+var yield = 'prop';
+var x = {};
+
+var counter = 0;
+
+for ([...[x[yield]]] of [[86]]) {
+ assert.sameValue(x.prop, 86);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array.js
new file mode 100644
index 0000000000..348bef9481
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-array.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-nested-array.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an array literal, it should be parsed parsed as a DestructuringAssignmentPattern and evaluated as a destructuring assignment. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+for ([...[x]] of [[1, 2, 3]]) {
+ assert.sameValue(x, 1);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-invalid.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-invalid.js
new file mode 100644
index 0000000000..3368e6ea71
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.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..of 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() {} }] of [[[]]]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-null.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-null.js
new file mode 100644
index 0000000000..c785308214
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-null.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-nested-obj-null.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an object literal and the iterable emits `null` as the only value, an array with a single `null` element should be used as the value of the nested DestructuringAssignment. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x, length;
+
+var counter = 0;
+
+for ([...{ 0: x, length }] of [[null]]) {
+ assert.sameValue(x, null);
+ assert.sameValue(length, 1);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-undefined-hole.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-undefined-hole.js
new file mode 100644
index 0000000000..51a4f6a384
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-undefined-hole.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-nested-obj-undefined-hole.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an array literal and the iterable is an array with a "hole", an array with a single `undefined` element should be used as the value of the nested DestructuringAssignment. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x = null;
+// Use the the top-level lexical scope for 'length' to provide compatibility with browsers
+// where length and name are properties of WindowProxy
+let length;
+
+var counter = 0;
+
+for ([...{ 0: x, length }] of [[ , ]]) {
+ assert.sameValue(x, undefined);
+ assert.sameValue(length, 1);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-undefined-own.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-undefined-own.js
new file mode 100644
index 0000000000..2c93d273ba
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-undefined-own.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-nested-obj-undefined-own.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an array literal and the iterable emits `undefined` as the only value, an array with a single `undefined` element should be used as the value of the nested DestructuringAssignment. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x = null;
+// Use the the top-level lexical scope for 'length' to provide compatibility with browsers
+// where length and name are properties of WindowProxy
+let length;
+
+var counter = 0;
+
+for ([...{ 0: x, length }] of [[undefined]]) {
+ assert.sameValue(x, undefined);
+ assert.sameValue(length, 1);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-undefined.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-undefined.js
new file mode 100644
index 0000000000..c3c28db4a7
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-undefined.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-nested-obj-undefined.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an obect literal and the iterable is emits no values, an empty array should be used as the value of the nested DestructuringAssignment. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x = null;
+// Use the the top-level lexical scope for 'length' to provide compatibility with browsers
+// where length and name are properties of WindowProxy
+let length;
+
+var counter = 0;
+
+for ([...{ 0: x, length }] of [[]]) {
+ assert.sameValue(x, undefined);
+ assert.sameValue(length, 0);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-yield-expr.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-yield-expr.js
new file mode 100644
index 0000000000..93a2cce8ac
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-yield-expr.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-nested-obj-yield-expr.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When a `yield` token appears within the Initializer of a nested destructuring assignment and within a generator function body, it should behave as a YieldExpression. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var iterationResult, iter, x;
+
+iter = (function*() {
+
+var counter = 0;
+
+for ([...{ x = yield }] of [[{}]]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+}());
+
+iterationResult = iter.next();
+
+assert.sameValue(iterationResult.value, undefined);
+assert.sameValue(iterationResult.done, false);
+assert.sameValue(x, undefined);
+
+iterationResult = iter.next(4);
+
+assert.sameValue(iterationResult.value, undefined);
+assert.sameValue(iterationResult.done, true);
+assert.sameValue(x, 4);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-yield-ident-invalid-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-yield-ident-invalid-strict.js
new file mode 100644
index 0000000000..7124f411be
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.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..of 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 }] of [[{}]]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-yield-ident-valid.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-yield-ident-valid.js
new file mode 100644
index 0000000000..7dc23a56cd
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj-yield-ident-valid.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-nested-obj-yield-ident-valid.case
+// - src/dstr-assignment/default/for-of.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..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, noStrict]
+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.
+ [...]
+---*/
+var yield = 2;
+var x;
+
+var counter = 0;
+
+for ([...{ x = yield }] of [[{}]]) {
+ assert.sameValue(x, 2);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj.js
new file mode 100644
index 0000000000..482ae1ca0a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-nested-obj.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-nested-obj.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an object literal, it should be parsed as a DestructuringAssignmentPattern and evaluated as a destructuring assignment. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+for ([...{ 1: x }] of [[1, 2, 3]]) {
+ assert.sameValue(x, 2);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-const.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-const.js
new file mode 100644
index 0000000000..56c60e050e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-const.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-put-const.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: The assignment target should obey `const` semantics. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [const, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+const c = null;
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ([ ...c ] of [[1]]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-let.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-let.js
new file mode 100644
index 0000000000..487d08cd62
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-let.js
@@ -0,0 +1,41 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-put-let.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: The assignment target should obey `let` semantics. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [let, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+
+var counter = 0;
+
+assert.throws(ReferenceError, function() {
+ for ([ ...x ] of [[]]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+let x;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-prop-ref-no-get.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-prop-ref-no-get.js
new file mode 100644
index 0000000000..110d37c5ae
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-prop-ref-no-get.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-put-prop-ref-no-get.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: If the DestructuringAssignmentTarget of an AssignmentElement is a PropertyReference, it should not be evaluated. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var setValue;
+var x = {
+ get y() {
+ throw new Test262Error('The property should not be accessed.');
+ },
+ set y(val) {
+ setValue = val;
+ }
+};
+
+var counter = 0;
+
+for ([...x.y] of [[23, 45, 99]]) {
+ assert.sameValue(setValue.length, 3);
+ assert.sameValue(setValue[0], 23);
+ assert.sameValue(setValue[1], 45);
+ assert.sameValue(setValue[2], 99);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-prop-ref-user-err-iter-close-skip.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-prop-ref-user-err-iter-close-skip.js
new file mode 100644
index 0000000000..2f6c3746d6
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-prop-ref-user-err-iter-close-skip.js
@@ -0,0 +1,83 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-put-prop-ref-user-err-iter-close-skip.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: IteratorClose is not called when value assignment produces an abrupt completion. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+
+ ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+ [...]
+ 5. Let result be the result of performing
+ IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
+ iteratorRecord as the argument
+ 6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+
+ AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
+
+ [...]
+ 4. Repeat while iteratorRecord.[[done]] is false
+ [...]
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ [...]
+ 5. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an
+ ArrayLiteral, then
+ a. Return PutValue(lref, A).
+
+---*/
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var iterator = {
+ next: function() {
+ nextCount += 1;
+ return { done: true };
+ },
+ return: function() {
+ returnCount += 1;
+ }
+};
+var obj = Object.defineProperty({}, 'poisoned', {
+ set: function(x) {
+ throw new Test262Error();
+ }
+});
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([...obj.poisoned] of [iterable]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-prop-ref-user-err.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-prop-ref-user-err.js
new file mode 100644
index 0000000000..45e6872020
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-prop-ref-user-err.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-put-prop-ref-user-err.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: Any error raised as a result of setting the value should be forwarded to the runtime. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x = {
+ set y(val) {
+ throw new Test262Error();
+ }
+};
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ([...x.y] of [[23]]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-prop-ref.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-prop-ref.js
new file mode 100644
index 0000000000..10b3ca6d3b
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-prop-ref.js
@@ -0,0 +1,41 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-put-prop-ref.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: The DestructuringAssignmentTarget of an AssignmentElement may be a PropertyReference. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x = {};
+
+var counter = 0;
+
+for ([...x.y] of [[4, 3, 2]]) {
+ assert.sameValue(x.y.length, 3);
+ assert.sameValue(x.y[0], 4);
+ assert.sameValue(x.y[1], 3);
+ assert.sameValue(x.y[2], 2);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-unresolvable-no-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-unresolvable-no-strict.js
new file mode 100644
index 0000000000..20b01f6336
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-unresolvable-no-strict.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-put-unresolvable-no-strict.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Outside of strict mode, if the the assignment target is an unresolvable reference, a new `var` binding should be created in the environment record. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, noStrict]
+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.
+ [...]
+---*/
+{
+
+var counter = 0;
+
+for ([ ...unresolvable ] of [[]]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+}
+
+assert.sameValue(unresolvable.length, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-unresolvable-strict-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-unresolvable-strict-strict.js
new file mode 100644
index 0000000000..a566c3f60f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-put-unresolvable-strict-strict.js
@@ -0,0 +1,40 @@
+'use strict';
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-put-unresolvable-strict.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: In strict mode, if the the assignment target is an unresolvable reference, a ReferenceError should be thrown. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, onlyStrict]
+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.
+ [...]
+---*/
+
+var counter = 0;
+
+assert.throws(ReferenceError, function() {
+ for ([ ...unresolvable ] of [[]]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-yield-expr.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-yield-expr.js
new file mode 100644
index 0000000000..d0c492b0a3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-yield-expr.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-yield-expr.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When a `yield` token appears within the DestructuringAssignmentTarget of an AssignmentRestElement and within the body of a generator function, it should behave as a YieldExpression. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x = {};
+var iterationResult, iter;
+
+iter = (function*() {
+
+var counter = 0;
+
+for ([...x[yield]] of [[33, 44, 55]]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+}());
+
+iterationResult = iter.next();
+
+assert.sameValue(iterationResult.value, undefined);
+assert.sameValue(iterationResult.done, false);
+assert.sameValue(x.prop, undefined);
+
+iterationResult = iter.next('prop');
+
+assert.sameValue(iterationResult.value, undefined);
+assert.sameValue(iterationResult.done, true);
+assert.sameValue(x.prop.length, 3);
+assert.sameValue(x.prop[0], 33);
+assert.sameValue(x.prop[1], 44);
+assert.sameValue(x.prop[2], 55);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-yield-ident-invalid-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-yield-ident-invalid-strict.js
new file mode 100644
index 0000000000..12b41221bd
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.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..of 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]] of [[]]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/array-rest-yield-ident-valid.js b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-yield-ident-valid.js
new file mode 100644
index 0000000000..9d2e19dff6
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/array-rest-yield-ident-valid.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-yield-ident-valid.case
+// - src/dstr-assignment/default/for-of.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..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, noStrict]
+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.
+ [...]
+---*/
+var yield = 'prop';
+var x = {};
+
+var counter = 0;
+
+for ([...x[yield]] of [[33, 44, 55]]) {
+ assert.sameValue(x.prop.length, 3);
+ assert.sameValue(x.prop[0], 33);
+ assert.sameValue(x.prop[1], 44);
+ assert.sameValue(x.prop[2], 55);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/browser.js b/js/src/tests/test262/language/statements/for-of/dstr/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/browser.js
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-init-iter-close.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-init-iter-close.js
new file mode 100644
index 0000000000..bdc6687660
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-init-iter-close.js
@@ -0,0 +1,72 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-init-iter-close.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Iterator is closed when not exhausted by pattern evaluation (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.5 Runtime Semantics: BindingInitialization
+
+ BindingPattern : ArrayBindingPattern
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, return ? IteratorClose(iterator,
+ result).
+ [...]
+
+---*/
+var doneCallCount = 0;
+var iter = {};
+iter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { value: null, done: false };
+ },
+ return: function() {
+ doneCallCount += 1;
+ return {};
+ }
+ };
+};
+
+var iterCount = 0;
+
+for (const [x] of [iter]) {
+ assert.sameValue(doneCallCount, 1);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-init-iter-get-err-array-prototype.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-init-iter-get-err-array-prototype.js
new file mode 100644
index 0000000000..7dcc91b449
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-init-iter-get-err-array-prototype.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-init-iter-get-err-array-prototype.case
+// - src/dstr-binding/error/for-of-const.template
+/*---
+description: Abrupt completion returned by GetIterator (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ Runtime Semantics: BindingInitialization
+
+ BindingPattern : ArrayBindingPattern
+
+ 1. Let iteratorRecord be ? GetIterator(value).
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ [...]
+ 4. Let iterator be ? Call(method, obj).
+
+ Call ( F, V [ , argumentsList ] )
+
+ [...]
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+
+---*/
+delete Array.prototype[Symbol.iterator];
+
+assert.throws(TypeError, function() {
+ for (const [x, y, z] of [[1, 2, 3]]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-init-iter-get-err.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-init-iter-get-err.js
new file mode 100644
index 0000000000..3caf29d81b
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-init-iter-get-err.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-init-iter-get-err.case
+// - src/dstr-binding/error/for-of-const.template
+/*---
+description: Abrupt completion returned by GetIterator (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.5 Runtime Semantics: BindingInitialization
+
+ BindingPattern : ArrayBindingPattern
+
+ 1. Let iterator be GetIterator(value).
+ 2. ReturnIfAbrupt(iterator).
+
+---*/
+var iter = {};
+iter[Symbol.iterator] = function() {
+ throw new Test262Error();
+};
+
+assert.throws(Test262Error, function() {
+ for (const [x] of [iter]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-init-iter-no-close.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-init-iter-no-close.js
new file mode 100644
index 0000000000..817876118a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-init-iter-no-close.js
@@ -0,0 +1,72 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-init-iter-no-close.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Iterator is not closed when exhausted by pattern evaluation (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.5 Runtime Semantics: BindingInitialization
+
+ BindingPattern : ArrayBindingPattern
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, return ? IteratorClose(iterator,
+ result).
+ [...]
+
+---*/
+var doneCallCount = 0;
+var iter = {};
+iter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { value: null, done: true };
+ },
+ return: function() {
+ doneCallCount += 1;
+ return {};
+ }
+ };
+};
+
+var iterCount = 0;
+
+for (const [x] of [iter]) {
+ assert.sameValue(doneCallCount, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-name-iter-val.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-name-iter-val.js
new file mode 100644
index 0000000000..7ae6f3fb2f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-name-iter-val.js
@@ -0,0 +1,71 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-name-iter-val.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: SingleNameBinding with normal value iteration (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (const [x, y, z] of [[1, 2, 3]]) {
+ assert.sameValue(x, 1);
+ assert.sameValue(y, 2);
+ assert.sameValue(z, 3);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-elem-init.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-elem-init.js
new file mode 100644
index 0000000000..217d2adf07
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-elem-init.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-elem-init.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: BindingElement with array binding pattern and initializer is used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ [...]
+ 2. If iteratorRecord.[[done]] is true, let v be undefined.
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be ? GetValue(defaultValue).
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+
+var iterCount = 0;
+
+for (const [[x, y, z] = [4, 5, 6]] of [[]]) {
+ assert.sameValue(x, 4);
+ assert.sameValue(y, 5);
+ assert.sameValue(z, 6);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-elem-iter.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-elem-iter.js
new file mode 100644
index 0000000000..8e557ea330
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-elem-iter.js
@@ -0,0 +1,64 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-elem-iter.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: BindingElement with array binding pattern and initializer is not used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ 1. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ [...]
+ e. Else,
+ i. Let v be IteratorValue(next).
+ [...]
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+
+var iterCount = 0;
+
+for (const [[x, y, z] = [4, 5, 6]] of [[[7, 8, 9]]]) {
+ assert.sameValue(x, 7);
+ assert.sameValue(y, 8);
+ assert.sameValue(z, 9);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-elision-init.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-elision-init.js
new file mode 100644
index 0000000000..9a2ebf1553
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-elision-init.js
@@ -0,0 +1,70 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-elision-init.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: BindingElement with array binding pattern and initializer is used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ [...]
+ 2. If iteratorRecord.[[done]] is true, let v be undefined.
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be ? GetValue(defaultValue).
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+
+---*/
+var first = 0;
+var second = 0;
+function* g() {
+ first += 1;
+ yield;
+ second += 1;
+};
+
+var iterCount = 0;
+
+for (const [[,] = g()] of [[]]) {
+ assert.sameValue(first, 1);
+ assert.sameValue(second, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-elision-iter.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-elision-iter.js
new file mode 100644
index 0000000000..a0ad26fc25
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-elision-iter.js
@@ -0,0 +1,67 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-elision-iter.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: BindingElement with array binding pattern and initializer is not used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ 1. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ [...]
+ e. Else,
+ i. Let v be IteratorValue(next).
+ [...]
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+
+---*/
+var callCount = 0;
+function* g() {
+ callCount += 1;
+};
+
+var iterCount = 0;
+
+for (const [[,] = g()] of [[[]]]) {
+ assert.sameValue(callCount, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-empty-init.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-empty-init.js
new file mode 100644
index 0000000000..0b7d99fda1
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-empty-init.js
@@ -0,0 +1,66 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-empty-init.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: BindingElement with array binding pattern and initializer is used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ [...]
+ 2. If iteratorRecord.[[done]] is true, let v be undefined.
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be ? GetValue(defaultValue).
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+
+---*/
+var initCount = 0;
+var iterCount = 0;
+var iter = function*() { iterCount += 1; }();
+
+var iterCount = 0;
+
+for (const [[] = function() { initCount += 1; return iter; }()] of [[]]) {
+ assert.sameValue(initCount, 1);
+ assert.sameValue(iterCount, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-empty-iter.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-empty-iter.js
new file mode 100644
index 0000000000..8b2d39fa32
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-empty-iter.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-empty-iter.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: BindingElement with array binding pattern and initializer is not used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ 1. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ [...]
+ e. Else,
+ i. Let v be IteratorValue(next).
+ [...]
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+var initCount = 0;
+
+var iterCount = 0;
+
+for (const [[] = function() { initCount += 1; }()] of [[[23]]]) {
+ assert.sameValue(initCount, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-rest-init.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-rest-init.js
new file mode 100644
index 0000000000..81d8dc2de2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-rest-init.js
@@ -0,0 +1,67 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-rest-init.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: BindingElement with array binding pattern and initializer is used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ [...]
+ 2. If iteratorRecord.[[done]] is true, let v be undefined.
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be ? GetValue(defaultValue).
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+var values = [2, 1, 3];
+
+var iterCount = 0;
+
+for (const [[...x] = values] of [[]]) {
+ assert(Array.isArray(x));
+ assert.sameValue(x[0], 2);
+ assert.sameValue(x[1], 1);
+ assert.sameValue(x[2], 3);
+ assert.sameValue(x.length, 3);
+ assert.notSameValue(x, values);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-rest-iter.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-rest-iter.js
new file mode 100644
index 0000000000..b09b6daabe
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-rest-iter.js
@@ -0,0 +1,70 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-rest-iter.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: BindingElement with array binding pattern and initializer is not used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ 1. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ [...]
+ e. Else,
+ i. Let v be IteratorValue(next).
+ [...]
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+var values = [2, 1, 3];
+var initCount = 0;
+
+var iterCount = 0;
+
+for (const [[...x] = function() { initCount += 1; }()] of [[values]]) {
+ assert(Array.isArray(x));
+ assert.sameValue(x[0], 2);
+ assert.sameValue(x[1], 1);
+ assert.sameValue(x[2], 3);
+ assert.sameValue(x.length, 3);
+ assert.notSameValue(x, values);
+ assert.sameValue(initCount, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-val-null.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-val-null.js
new file mode 100644
index 0000000000..d380b761f3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-ary-val-null.js
@@ -0,0 +1,64 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-val-null.case
+// - src/dstr-binding/error/for-of-const.template
+/*---
+description: Nested array destructuring with a null value (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPattern Initializeropt
+
+ 1. If iteratorRecord.[[done]] is false, then
+ [...]
+ e. Else
+ i. Let v be IteratorValue(next).
+ [...]
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+
+ 13.3.3.5 Runtime Semantics: BindingInitialization
+
+ BindingPattern : ArrayBindingPattern
+
+ 1. Let iterator be GetIterator(value).
+ 2. ReturnIfAbrupt(iterator).
+---*/
+
+assert.throws(TypeError, function() {
+ for (const [[x]] of [[null]]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-exhausted.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-exhausted.js
new file mode 100644
index 0000000000..00f39a397a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-exhausted.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-exhausted.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Destructuring initializer with an exhausted iterator (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v).
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (const [x = 23] of [[]]) {
+ assert.sameValue(x, 23);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-fn-name-arrow.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-fn-name-arrow.js
new file mode 100644
index 0000000000..0d77af2052
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-fn-name-arrow.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-fn-name-arrow.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: SingleNameBinding does assign name to arrow functions (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v).
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (const [arrow = () => {}] of [[]]) {
+ assert.sameValue(arrow.name, 'arrow');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-fn-name-class.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-fn-name-class.js
new file mode 100644
index 0000000000..d536028996
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-fn-name-class.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-fn-name-class.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: SingleNameBinding assigns `name` to "anonymous" classes (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v).
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (const [cls = class {}, xCls = class X {}, xCls2 = class { static name() {} }] of [[]]) {
+ assert.sameValue(cls.name, 'cls');
+ assert.notSameValue(xCls.name, 'xCls');
+ assert.notSameValue(xCls2.name, 'xCls2');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-fn-name-cover.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-fn-name-cover.js
new file mode 100644
index 0000000000..a48fa92448
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-fn-name-cover.js
@@ -0,0 +1,64 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-fn-name-cover.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: SingleNameBinding does assign name to "anonymous" functions "through" cover grammar (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v).
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (const [cover = (function () {}), xCover = (0, function() {})] of [[]]) {
+ assert.sameValue(cover.name, 'cover');
+ assert.notSameValue(xCover.name, 'xCover');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-fn-name-fn.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-fn-name-fn.js
new file mode 100644
index 0000000000..023f9247fc
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-fn-name-fn.js
@@ -0,0 +1,64 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-fn-name-fn.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: SingleNameBinding assigns name to "anonymous" functions (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v).
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (const [fn = function () {}, xFn = function x() {}] of [[]]) {
+ assert.sameValue(fn.name, 'fn');
+ assert.notSameValue(xFn.name, 'xFn');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-fn-name-gen.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-fn-name-gen.js
new file mode 100644
index 0000000000..e33c8f1c06
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-fn-name-gen.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-fn-name-gen.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: SingleNameBinding assigns name to "anonymous" generator functions (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v).
+ 8. Return InitializeReferencedBinding(lhs, v).
+
+---*/
+
+var iterCount = 0;
+
+for (const [gen = function* () {}, xGen = function* x() {}] of [[]]) {
+ assert.sameValue(gen.name, 'gen');
+ assert.notSameValue(xGen.name, 'xGen');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-hole.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-hole.js
new file mode 100644
index 0000000000..671c1fe0a0
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-hole.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-hole.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Destructuring initializer with a "hole" (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+ SingleNameBinding : BindingIdentifier Initializeropt
+ [...] 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v). 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (const [x = 23] of [[,]]) {
+ assert.sameValue(x, 23);
+ // another statement
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-skipped.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-skipped.js
new file mode 100644
index 0000000000..287e32bcd7
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-skipped.js
@@ -0,0 +1,67 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-skipped.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Destructuring initializer is not evaluated when value is not `undefined` (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v).
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+var initCount = 0;
+function counter() {
+ initCount += 1;
+}
+
+var iterCount = 0;
+
+for (const [w = counter(), x = counter(), y = counter(), z = counter()] of [[null, 0, false, '']]) {
+ assert.sameValue(w, null);
+ assert.sameValue(x, 0);
+ assert.sameValue(y, false);
+ assert.sameValue(z, '');
+ assert.sameValue(initCount, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-throws.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-throws.js
new file mode 100644
index 0000000000..eac4b83873
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-throws.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-throws.case
+// - src/dstr-binding/error/for-of-const.template
+/*---
+description: Destructuring initializer returns an abrupt completion (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+---*/
+
+assert.throws(Test262Error, function() {
+ for (const [x = (function() { throw new Test262Error(); })()] of [[undefined]]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-undef.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-undef.js
new file mode 100644
index 0000000000..1a3db28d11
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-undef.js
@@ -0,0 +1,61 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-undef.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Destructuring initializer with an undefined value (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v).
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (const [x = 23] of [[undefined]]) {
+ assert.sameValue(x, 23);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-unresolvable.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-unresolvable.js
new file mode 100644
index 0000000000..c0169e8a17
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-unresolvable.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-unresolvable.case
+// - src/dstr-binding/error/for-of-const.template
+/*---
+description: Destructuring initializer is an unresolvable reference (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+
+ 6.2.3.1 GetValue (V)
+
+ 1. ReturnIfAbrupt(V).
+ 2. If Type(V) is not Reference, return V.
+ 3. Let base be GetBase(V).
+ 4. If IsUnresolvableReference(V), throw a ReferenceError exception.
+---*/
+
+assert.throws(ReferenceError, function() {
+ for (const [ x = unresolvableReference ] of [[]]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-iter-complete.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-iter-complete.js
new file mode 100644
index 0000000000..2776aab08d
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-iter-complete.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-iter-complete.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: SingleNameBinding when value iteration completes (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (const [x] of [[]]) {
+ assert.sameValue(x, undefined);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-iter-done.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-iter-done.js
new file mode 100644
index 0000000000..1407655409
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-iter-done.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-iter-done.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: SingleNameBinding when value iteration was completed previously (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ [...]
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (const [_, x] of [[]]) {
+ assert.sameValue(x, undefined);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-iter-step-err.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-iter-step-err.js
new file mode 100644
index 0000000000..6f93b69dd5
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-iter-step-err.js
@@ -0,0 +1,64 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-iter-step-err.case
+// - src/dstr-binding/error/for-of-const.template
+/*---
+description: Error forwarding when IteratorStep returns an abrupt completion (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+
+---*/
+var g = {};
+g[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ throw new Test262Error();
+ }
+ };
+};
+
+assert.throws(Test262Error, function() {
+ for (const [x] of [g]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-iter-val-array-prototype.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-iter-val-array-prototype.js
new file mode 100644
index 0000000000..ef03673a4e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-iter-val-array-prototype.js
@@ -0,0 +1,81 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-iter-val-array-prototype.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Array destructuring uses overriden Array.prototype[Symbol.iterator] (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializer_opt
+
+ 1. Let bindingId be StringValue of BindingIdentifier.
+ 2. Let lhs be ? ResolveBinding(bindingId, environment).
+ 3. If iteratorRecord.[[Done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord).
+ b. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[Done]] to true.
+ e. Else,
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ iii. ReturnIfAbrupt(v).
+ [...]
+ 7. Return InitializeReferencedBinding(lhs, v).
+
+---*/
+Array.prototype[Symbol.iterator] = function* () {
+ if (this.length > 0) {
+ yield this[0];
+ }
+ if (this.length > 1) {
+ yield this[1];
+ }
+ if (this.length > 2) {
+ yield 42;
+ }
+};
+
+var iterCount = 0;
+
+for (const [x, y, z] of [[1, 2, 3]]) {
+ assert.sameValue(x, 1);
+ assert.sameValue(y, 2);
+ assert.sameValue(z, 42);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-iter-val-err.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-iter-val-err.js
new file mode 100644
index 0000000000..c52b85fc58
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-iter-val-err.js
@@ -0,0 +1,75 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-iter-val-err.case
+// - src/dstr-binding/error/for-of-const.template
+/*---
+description: Error forwarding when IteratorValue returns an abrupt completion (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set iteratorRecord.[[done]] to
+ true.
+ iii. ReturnIfAbrupt(v).
+
+---*/
+var poisonedValue = Object.defineProperty({}, 'value', {
+ get: function() {
+ throw new Test262Error();
+ }
+});
+var g = {};
+g[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return poisonedValue;
+ }
+ };
+};
+
+assert.throws(Test262Error, function() {
+ for (const [x] of [g]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-iter-val.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-iter-val.js
new file mode 100644
index 0000000000..9751e7a674
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-id-iter-val.js
@@ -0,0 +1,71 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-iter-val.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: SingleNameBinding when value iteration was completed previously (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (const [x, y, z] of [[1, 2, 3]]) {
+ assert.sameValue(x, 1);
+ assert.sameValue(y, 2);
+ assert.sameValue(z, 3);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-obj-id-init.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-obj-id-init.js
new file mode 100644
index 0000000000..38ef7a9261
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-obj-id-init.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-obj-id-init.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: BindingElement with object binding pattern and initializer is used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ [...]
+ 2. If iteratorRecord.[[done]] is true, let v be undefined.
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be ? GetValue(defaultValue).
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+
+var iterCount = 0;
+
+for (const [{ x, y, z } = { x: 44, y: 55, z: 66 }] of [[]]) {
+ assert.sameValue(x, 44);
+ assert.sameValue(y, 55);
+ assert.sameValue(z, 66);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-obj-id.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-obj-id.js
new file mode 100644
index 0000000000..744ef995e6
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-obj-id.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-obj-id.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: BindingElement with object binding pattern and initializer is not used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ [...]
+ 2. If iteratorRecord.[[done]] is true, let v be undefined.
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be ? GetValue(defaultValue).
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+
+var iterCount = 0;
+
+for (const [{ x, y, z } = { x: 44, y: 55, z: 66 }] of [[{ x: 11, y: 22, z: 33 }]]) {
+ assert.sameValue(x, 11);
+ assert.sameValue(y, 22);
+ assert.sameValue(z, 33);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-obj-prop-id-init.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-obj-prop-id-init.js
new file mode 100644
index 0000000000..600ac4b074
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-obj-prop-id-init.js
@@ -0,0 +1,73 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-obj-prop-id-init.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: BindingElement with object binding pattern and initializer is used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ [...]
+ 2. If iteratorRecord.[[done]] is true, let v be undefined.
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be ? GetValue(defaultValue).
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+
+var iterCount = 0;
+
+for (const [{ u: v, w: x, y: z } = { u: 444, w: 555, y: 666 }] of [[]]) {
+ assert.sameValue(v, 444);
+ assert.sameValue(x, 555);
+ assert.sameValue(z, 666);
+
+ assert.throws(ReferenceError, function() {
+ u;
+ });
+ assert.throws(ReferenceError, function() {
+ w;
+ });
+ assert.throws(ReferenceError, function() {
+ y;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-obj-prop-id.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-obj-prop-id.js
new file mode 100644
index 0000000000..1d9a8cbb8d
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-obj-prop-id.js
@@ -0,0 +1,73 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-obj-prop-id.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: BindingElement with object binding pattern and initializer is not used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ [...]
+ 2. If iteratorRecord.[[done]] is true, let v be undefined.
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be ? GetValue(defaultValue).
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+
+var iterCount = 0;
+
+for (const [{ u: v, w: x, y: z } = { u: 444, w: 555, y: 666 }] of [[{ u: 777, w: 888, y: 999 }]]) {
+ assert.sameValue(v, 777);
+ assert.sameValue(x, 888);
+ assert.sameValue(z, 999);
+
+ assert.throws(ReferenceError, function() {
+ u;
+ });
+ assert.throws(ReferenceError, function() {
+ w;
+ });
+ assert.throws(ReferenceError, function() {
+ y;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-obj-val-null.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-obj-val-null.js
new file mode 100644
index 0000000000..5f6d0743a2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-obj-val-null.js
@@ -0,0 +1,64 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-obj-val-null.case
+// - src/dstr-binding/error/for-of-const.template
+/*---
+description: Nested object destructuring with a null value (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPattern Initializeropt
+
+ 1. If iteratorRecord.[[done]] is false, then
+ [...]
+ e. Else
+ i. Let v be IteratorValue(next).
+ [...]
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+
+ 13.3.3.5 Runtime Semantics: BindingInitialization
+
+ BindingPattern : ObjectBindingPattern
+
+ 1. Let valid be RequireObjectCoercible(value).
+ 2. ReturnIfAbrupt(valid).
+---*/
+
+assert.throws(TypeError, function() {
+ for (const [{ x }] of [[null]]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-obj-val-undef.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-obj-val-undef.js
new file mode 100644
index 0000000000..25977c2400
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elem-obj-val-undef.js
@@ -0,0 +1,64 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-obj-val-undef.case
+// - src/dstr-binding/error/for-of-const.template
+/*---
+description: Nested object destructuring with a value of `undefined` (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPattern Initializeropt
+
+ 1. If iteratorRecord.[[done]] is false, then
+ [...]
+ e. Else
+ i. Let v be IteratorValue(next).
+ [...]
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+
+ 13.3.3.5 Runtime Semantics: BindingInitialization
+
+ BindingPattern : ObjectBindingPattern
+
+ 1. Let valid be RequireObjectCoercible(value).
+ 2. ReturnIfAbrupt(valid).
+---*/
+
+assert.throws(TypeError, function() {
+ for (const [{ x }] of [[]]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elision-exhausted.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elision-exhausted.js
new file mode 100644
index 0000000000..3952eff05c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elision-exhausted.js
@@ -0,0 +1,68 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elision-exhausted.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Elision accepts exhausted iterator (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ ArrayBindingPattern : [ Elision ]
+
+ 1. Return the result of performing
+ IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord
+ as the argument.
+
+ 12.14.5.3 Runtime Semantics: IteratorDestructuringAssignmentEvaluation
+
+ Elision : ,
+
+ 1. If iteratorRecord.[[done]] is false, then
+ [...]
+ 2. Return NormalCompletion(empty).
+
+---*/
+var iter = function*() {}();
+iter.next();
+
+var iterCount = 0;
+
+for (const [,] of [iter]) {
+
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elision-iter-close.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elision-iter-close.js
new file mode 100644
index 0000000000..eb8a8b0b96
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elision-iter-close.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elision-iter-close.case
+// - src/dstr-binding/iter-close/for-of-const.template
+/*---
+description: The iterator is properly consumed by the destructuring pattern (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+---*/
+const iter = (function* () {
+ yield;
+ yield;
+})();
+
+
+function fn() {
+ for (const [,] of [iter]) {
+ return;
+ }
+}
+
+fn();
+
+assert.sameValue(iter.next().done, true, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elision-step-err.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elision-step-err.js
new file mode 100644
index 0000000000..dcd3155f83
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elision-step-err.js
@@ -0,0 +1,71 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elision-step-err.case
+// - src/dstr-binding/error/for-of-const.template
+/*---
+description: Elision advances iterator and forwards abrupt completions (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ ArrayBindingPattern : [ Elision ]
+
+ 1. Return the result of performing
+ IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord
+ as the argument.
+
+ 12.14.5.3 Runtime Semantics: IteratorDestructuringAssignmentEvaluation
+
+ Elision : ,
+
+ 1. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+
+---*/
+var following = 0;
+var iter =function* () {
+ throw new Test262Error();
+ following += 1;
+}();
+
+assert.throws(Test262Error, function() {
+ for (const [,] of [iter]) {
+ return;
+ }
+});
+
+iter.next();
+assert.sameValue(following, 0, 'Iterator was properly closed.');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elision.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elision.js
new file mode 100644
index 0000000000..b42eaaf2a8
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-elision.js
@@ -0,0 +1,77 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elision.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Elision advances iterator (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ ArrayBindingPattern : [ Elision ]
+
+ 1. Return the result of performing
+ IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord
+ as the argument.
+
+ 12.14.5.3 Runtime Semantics: IteratorDestructuringAssignmentEvaluation
+
+ Elision : ,
+
+ 1. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ 2. Return NormalCompletion(empty).
+
+---*/
+var first = 0;
+var second = 0;
+function* g() {
+ first += 1;
+ yield;
+ second += 1;
+};
+
+var iterCount = 0;
+
+for (const [,] of [g()]) {
+ assert.sameValue(first, 1);
+ assert.sameValue(second, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-empty.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-empty.js
new file mode 100644
index 0000000000..7e5df06e2e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-empty.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-empty.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: No iteration occurs for an "empty" array binding pattern (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ ArrayBindingPattern : [ ]
+
+ 1. Return NormalCompletion(empty).
+
+---*/
+var iterations = 0;
+var iter = function*() {
+ iterations += 1;
+}();
+
+var iterCount = 0;
+
+for (const [] of [iter]) {
+ assert.sameValue(iterations, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-init-err.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-init-err.js
new file mode 100644
index 0000000000..f294826871
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-init-err.js
@@ -0,0 +1,18 @@
+// |reftest| error:SyntaxError
+// Copyright (C) 2019 Aleksey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-iteration-statements
+description: >
+ Initializer is not allowed in head's ForDeclaration position.
+info: |
+ IterationStatement:
+ for (ForDeclaration of AssignmentExpression) Statement
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for (const [x] = 1 of []) {}
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-ary-elem.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-ary-elem.js
new file mode 100644
index 0000000000..a8bfc671b0
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-ary-elem.js
@@ -0,0 +1,84 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-ary-elem.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Rest element containing an array BindingElementList pattern (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingRestElement : ... BindingPattern
+
+ 1. Let A be ArrayCreate(0).
+ [...]
+ 3. Repeat
+ [...]
+ b. If iteratorRecord.[[done]] is true, then
+ i. Return the result of performing BindingInitialization of
+ BindingPattern with A and environment as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (const [...[x, y, z]] of [[3, 4, 5]]) {
+ assert.sameValue(x, 3);
+ assert.sameValue(y, 4);
+ assert.sameValue(z, 5);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-ary-elision.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-ary-elision.js
new file mode 100644
index 0000000000..ea7ddad36f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-ary-elision.js
@@ -0,0 +1,90 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-ary-elision.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Rest element containing an elision (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingRestElement : ... BindingPattern
+
+ 1. Let A be ArrayCreate(0).
+ [...]
+ 3. Repeat
+ [...]
+ b. If iteratorRecord.[[done]] is true, then
+ i. Return the result of performing BindingInitialization of
+ BindingPattern with A and environment as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ ArrayBindingPattern : [ Elision ]
+
+ 1. Return the result of performing
+ IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord
+ as the argument.
+
+ 12.14.5.3 Runtime Semantics: IteratorDestructuringAssignmentEvaluation
+
+ Elision : ,
+
+ 1. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ 2. Return NormalCompletion(empty).
+
+---*/
+var first = 0;
+var second = 0;
+function* g() {
+ first += 1;
+ yield;
+ second += 1;
+};
+
+var iterCount = 0;
+
+for (const [...[,]] of [g()]) {
+ assert.sameValue(first, 1);
+ assert.sameValue(second, 1);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-ary-empty.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-ary-empty.js
new file mode 100644
index 0000000000..5084f6f3e6
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-ary-empty.js
@@ -0,0 +1,73 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-ary-empty.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Rest element containing an "empty" array pattern (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingRestElement : ... BindingPattern
+
+ 1. Let A be ArrayCreate(0).
+ [...]
+ 3. Repeat
+ [...]
+ b. If iteratorRecord.[[done]] is true, then
+ i. Return the result of performing BindingInitialization of
+ BindingPattern with A and environment as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ ArrayBindingPattern : [ ]
+
+ 1. Return NormalCompletion(empty).
+
+---*/
+var iterations = 0;
+var iter = function*() {
+ iterations += 1;
+}();
+
+var iterCount = 0;
+
+for (const [...[]] of [iter]) {
+ assert.sameValue(iterations, 1);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-ary-rest.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-ary-rest.js
new file mode 100644
index 0000000000..248cac83a4
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-ary-rest.js
@@ -0,0 +1,69 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-ary-rest.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Rest element containing a rest element (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingRestElement : ... BindingPattern
+
+ 1. Let A be ArrayCreate(0).
+ [...]
+ 3. Repeat
+ [...]
+ b. If iteratorRecord.[[done]] is true, then
+ i. Return the result of performing BindingInitialization of
+ BindingPattern with A and environment as the arguments.
+ [...]
+---*/
+var values = [1, 2, 3];
+
+var iterCount = 0;
+
+for (const [...[...x]] of [values]) {
+ assert(Array.isArray(x));
+ assert.sameValue(x.length, 3);
+ assert.sameValue(x[0], 1);
+ assert.sameValue(x[1], 2);
+ assert.sameValue(x[2], 3);
+ assert.notSameValue(x, values);
+
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-direct.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-direct.js
new file mode 100644
index 0000000000..023443c909
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-direct.js
@@ -0,0 +1,64 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-id-direct.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Lone rest element (direct binding) (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+includes: [compareArray.js]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ Runtime Semantics: IteratorBindingInitialization
+
+ BindingRestElement : ... BindingIdentifier
+
+ [...]
+ 2. Let A be ! ArrayCreate(0).
+ 3. Let n be 0.
+ 4. Repeat,
+ [...]
+ f. Perform ! CreateDataPropertyOrThrow(A, ! ToString(n), nextValue).
+ g. Set n to n + 1.
+
+---*/
+
+var iterCount = 0;
+
+for (const [...x] of [[1]]) {
+ assert(Array.isArray(x));
+ assert.compareArray(x, [1]);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-elision-next-err.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-elision-next-err.js
new file mode 100644
index 0000000000..a0cf9ee911
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-elision-next-err.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-id-elision-next-err.case
+// - src/dstr-binding/error/for-of-const.template
+/*---
+description: Rest element following elision elements (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+ ArrayBindingPattern : [ Elisionopt BindingRestElement ]
+ 1. If Elision is present, then
+ a. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of Elision with
+ iteratorRecord as the argument.
+ b. ReturnIfAbrupt(status).
+ 2. Return the result of performing IteratorBindingInitialization for
+ BindingRestElement with iteratorRecord and environment as arguments.
+
+---*/
+var iter = (function*() { throw new Test262Error(); })();
+
+assert.throws(Test262Error, function() {
+ for (const [, ...x] of [iter]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-elision.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-elision.js
new file mode 100644
index 0000000000..d2479bbedd
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-elision.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-id-elision.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Rest element following elision elements (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+ ArrayBindingPattern : [ Elisionopt BindingRestElement ]
+ 1. If Elision is present, then
+ a. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of Elision with
+ iteratorRecord as the argument.
+ b. ReturnIfAbrupt(status).
+ 2. Return the result of performing IteratorBindingInitialization for
+ BindingRestElement with iteratorRecord and environment as arguments.
+---*/
+var values = [1, 2, 3, 4, 5];
+
+var iterCount = 0;
+
+for (const [ , , ...x] of [values]) {
+ assert(Array.isArray(x));
+ assert.sameValue(x.length, 3);
+ assert.sameValue(x[0], 3);
+ assert.sameValue(x[1], 4);
+ assert.sameValue(x[2], 5);
+ assert.notSameValue(x, values);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-exhausted.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-exhausted.js
new file mode 100644
index 0000000000..c2e7693af8
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-exhausted.js
@@ -0,0 +1,61 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-id-exhausted.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: RestElement applied to an exhausted iterator (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+ BindingRestElement : ... BindingIdentifier
+ 1. Let lhs be ResolveBinding(StringValue of BindingIdentifier,
+ environment).
+ 2. ReturnIfAbrupt(lhs). 3. Let A be ArrayCreate(0). 4. Let n=0. 5. Repeat,
+ [...]
+ b. If iteratorRecord.[[done]] is true, then
+ i. If environment is undefined, return PutValue(lhs, A).
+ ii. Return InitializeReferencedBinding(lhs, A).
+
+---*/
+
+var iterCount = 0;
+
+for (const [, , ...x] of [[1, 2]]) {
+ assert(Array.isArray(x));
+ assert.sameValue(x.length, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-iter-close.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-iter-close.js
new file mode 100644
index 0000000000..0534ab4866
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-iter-close.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-id-iter-close.case
+// - src/dstr-binding/iter-close/for-of-const.template
+/*---
+description: The iterator is properly consumed by the destructuring pattern (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+---*/
+const iter = (function* () {
+ yield;
+ yield;
+})();
+
+
+function fn() {
+ for (const [...x] of [iter]) {
+ return;
+ }
+}
+
+fn();
+
+assert.sameValue(iter.next().done, true, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-iter-step-err.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-iter-step-err.js
new file mode 100644
index 0000000000..fe2263684a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-iter-step-err.js
@@ -0,0 +1,68 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-id-iter-step-err.case
+// - src/dstr-binding/error/for-of-const.template
+/*---
+description: Error forwarding when IteratorStep returns an abrupt completion (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+ BindingRestElement : ... BindingIdentifier
+ 1. Let lhs be ResolveBinding(StringValue of BindingIdentifier,
+ environment).
+ 2. ReturnIfAbrupt(lhs). 3. Let A be ArrayCreate(0). 4. Let n=0. 5. Repeat,
+ a. If iteratorRecord.[[done]] is false,
+ i. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ ii. If next is an abrupt completion, set iteratorRecord.[[done]] to
+ true.
+ iii. ReturnIfAbrupt(next).
+
+---*/
+var first = 0;
+var second = 0;
+var iter = function*() {
+ first += 1;
+ throw new Test262Error();
+ second += 1;
+}();
+
+assert.throws(Test262Error, function() {
+ for (const [...x] of [iter]) {
+ return;
+ }
+});
+
+iter.next();
+assert.sameValue(first, 1);
+assert.sameValue(second, 0, 'Iterator is closed following abrupt completion.');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-iter-val-err.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-iter-val-err.js
new file mode 100644
index 0000000000..12472d517c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id-iter-val-err.js
@@ -0,0 +1,70 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-id-iter-val-err.case
+// - src/dstr-binding/error/for-of-const.template
+/*---
+description: Error forwarding when IteratorValue returns an abrupt completion (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+ BindingRestElement : ... BindingIdentifier
+ 1. Let lhs be ResolveBinding(StringValue of BindingIdentifier,
+ environment).
+ 2. ReturnIfAbrupt(lhs). 3. Let A be ArrayCreate(0). 4. Let n=0. 5. Repeat,
+ [...]
+ c. Let nextValue be IteratorValue(next).
+ d. If nextValue is an abrupt completion, set iteratorRecord.[[done]] to
+ true.
+ e. ReturnIfAbrupt(nextValue).
+
+---*/
+var poisonedValue = Object.defineProperty({}, 'value', {
+ get: function() {
+ throw new Test262Error();
+ }
+});
+var iter = {};
+iter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return poisonedValue;
+ }
+ };
+};
+
+assert.throws(Test262Error, function() {
+ for (const [...x] of [iter]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id.js
new file mode 100644
index 0000000000..2c4b3fc3a3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-id.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-id.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Lone rest element (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+ BindingRestElement : ... BindingIdentifier
+ [...] 3. Let A be ArrayCreate(0). [...] 5. Repeat
+ [...]
+ f. Let status be CreateDataProperty(A, ToString (n), nextValue).
+ [...]
+---*/
+var values = [1, 2, 3];
+
+var iterCount = 0;
+
+for (const [...x] of [values]) {
+ assert(Array.isArray(x));
+ assert.sameValue(x.length, 3);
+ assert.sameValue(x[0], 1);
+ assert.sameValue(x[1], 2);
+ assert.sameValue(x[2], 3);
+ assert.notSameValue(x, values);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-init-ary.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-init-ary.js
new file mode 100644
index 0000000000..d20f6a8c56
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-init-ary.js
@@ -0,0 +1,58 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-init-ary.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Rest element (nested array pattern) does not support initializer (for-of 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 ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+ ArrayBindingPattern[Yield] :
+ [ Elisionopt BindingRestElement[?Yield]opt ]
+ [ BindingElementList[?Yield] ]
+ [ BindingElementList[?Yield] , Elisionopt BindingRestElement[?Yield]opt ]
+---*/
+$DONOTEVALUATE();
+
+var iterCount = 0;
+
+for (const [...[ x ] = []] of [[]]) {
+
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-init-id.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-init-id.js
new file mode 100644
index 0000000000..eeb53cf677
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-init-id.js
@@ -0,0 +1,58 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-init-id.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Rest element (identifier) does not support initializer (for-of 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 ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+ ArrayBindingPattern[Yield] :
+ [ Elisionopt BindingRestElement[?Yield]opt ]
+ [ BindingElementList[?Yield] ]
+ [ BindingElementList[?Yield] , Elisionopt BindingRestElement[?Yield]opt ]
+---*/
+$DONOTEVALUATE();
+
+var iterCount = 0;
+
+for (const [...x = []] of [[]]) {
+
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-init-obj.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-init-obj.js
new file mode 100644
index 0000000000..e8e3d80256
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-init-obj.js
@@ -0,0 +1,58 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-init-obj.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Rest element (nested object pattern) does not support initializer (for-of 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 ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+ ArrayBindingPattern[Yield] :
+ [ Elisionopt BindingRestElement[?Yield]opt ]
+ [ BindingElementList[?Yield] ]
+ [ BindingElementList[?Yield] , Elisionopt BindingRestElement[?Yield]opt ]
+---*/
+$DONOTEVALUATE();
+
+var iterCount = 0;
+
+for (const [...{ x } = []] of [[]]) {
+
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-not-final-ary.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-not-final-ary.js
new file mode 100644
index 0000000000..897ad82b3b
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-not-final-ary.js
@@ -0,0 +1,58 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-not-final-ary.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Rest element (array binding pattern) may not be followed by any element (for-of 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 ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+ ArrayBindingPattern[Yield] :
+ [ Elisionopt BindingRestElement[?Yield]opt ]
+ [ BindingElementList[?Yield] ]
+ [ BindingElementList[?Yield] , Elisionopt BindingRestElement[?Yield]opt ]
+---*/
+$DONOTEVALUATE();
+
+var iterCount = 0;
+
+for (const [...[x], y] of [[1, 2, 3]]) {
+
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-not-final-id.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-not-final-id.js
new file mode 100644
index 0000000000..bbd9a15bb2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-not-final-id.js
@@ -0,0 +1,58 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-not-final-id.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Rest element (identifier) may not be followed by any element (for-of 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 ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+ ArrayBindingPattern[Yield] :
+ [ Elisionopt BindingRestElement[?Yield]opt ]
+ [ BindingElementList[?Yield] ]
+ [ BindingElementList[?Yield] , Elisionopt BindingRestElement[?Yield]opt ]
+---*/
+$DONOTEVALUATE();
+
+var iterCount = 0;
+
+for (const [...x, y] of [[1, 2, 3]]) {
+
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-not-final-obj.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-not-final-obj.js
new file mode 100644
index 0000000000..0e6ec2518c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-not-final-obj.js
@@ -0,0 +1,58 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-not-final-obj.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Rest element (object binding pattern) may not be followed by any element (for-of 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 ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+ ArrayBindingPattern[Yield] :
+ [ Elisionopt BindingRestElement[?Yield]opt ]
+ [ BindingElementList[?Yield] ]
+ [ BindingElementList[?Yield] , Elisionopt BindingRestElement[?Yield]opt ]
+---*/
+$DONOTEVALUATE();
+
+var iterCount = 0;
+
+for (const [...{ x }, y] of [[1, 2, 3]]) {
+
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-obj-id.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-obj-id.js
new file mode 100644
index 0000000000..de0e9babd6
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-obj-id.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-obj-id.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Rest element containing an object binding pattern (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingRestElement : ... BindingPattern
+
+ 1. Let A be ArrayCreate(0).
+ [...]
+ 3. Repeat
+ [...]
+ b. If iteratorRecord.[[done]] is true, then
+ i. Return the result of performing BindingInitialization of
+ BindingPattern with A and environment as the arguments.
+ [...]
+---*/
+
+var iterCount = 0;
+
+for (const [...{ length }] of [[1, 2, 3]]) {
+ assert.sameValue(length, 3);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-obj-prop-id.js b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-obj-prop-id.js
new file mode 100644
index 0000000000..d5ddf64601
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-ary-ptrn-rest-obj-prop-id.js
@@ -0,0 +1,69 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-obj-prop-id.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Rest element containing an object binding pattern (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingRestElement : ... BindingPattern
+
+ 1. Let A be ArrayCreate(0).
+ [...]
+ 3. Repeat
+ [...]
+ b. If iteratorRecord.[[done]] is true, then
+ i. Return the result of performing BindingInitialization of
+ BindingPattern with A and environment as the arguments.
+ [...]
+---*/
+let length = "outer";
+
+var iterCount = 0;
+
+for (const [...{ 0: v, 1: w, 2: x, 3: y, length: z }] of [[7, 8, 9]]) {
+ assert.sameValue(v, 7);
+ assert.sameValue(w, 8);
+ assert.sameValue(x, 9);
+ assert.sameValue(y, undefined);
+ assert.sameValue(z, 3);
+
+ assert.sameValue(length, "outer", "the length prop is not set as a binding name");
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-init-null.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-init-null.js
new file mode 100644
index 0000000000..53a699c8b8
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-init-null.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-init-null.case
+// - src/dstr-binding/error/for-of-const.template
+/*---
+description: Value specifed for object binding pattern must be object coercible (null) (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ Runtime Semantics: BindingInitialization
+
+ ObjectBindingPattern : { }
+
+ 1. Return NormalCompletion(empty).
+---*/
+
+assert.throws(TypeError, function() {
+ for (const {} of [null]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-init-undefined.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-init-undefined.js
new file mode 100644
index 0000000000..9a0540f9e6
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-init-undefined.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-init-undefined.case
+// - src/dstr-binding/error/for-of-const.template
+/*---
+description: Value specifed for object binding pattern must be object coercible (undefined) (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ Runtime Semantics: BindingInitialization
+
+ ObjectBindingPattern : { }
+
+ 1. Return NormalCompletion(empty).
+---*/
+
+assert.throws(TypeError, function() {
+ for (const {} of [undefined]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-empty.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-empty.js
new file mode 100644
index 0000000000..fc85ac0e64
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-empty.js
@@ -0,0 +1,61 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-empty.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: No property access occurs for an "empty" object binding pattern (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ Runtime Semantics: BindingInitialization
+
+ ObjectBindingPattern : { }
+
+ 1. Return NormalCompletion(empty).
+---*/
+var accessCount = 0;
+var obj = Object.defineProperty({}, 'attr', {
+ get: function() {
+ accessCount += 1;
+ }
+});
+
+var iterCount = 0;
+
+for (const {} of [obj]) {
+ assert.sameValue(accessCount, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-get-value-err.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-get-value-err.js
new file mode 100644
index 0000000000..0c3baa9c5e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-get-value-err.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-get-value-err.case
+// - src/dstr-binding/error/for-of-const.template
+/*---
+description: Error thrown when accessing the corresponding property of the value object (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. Let v be GetV(value, propertyName).
+ 5. ReturnIfAbrupt(v).
+---*/
+var poisonedProperty = Object.defineProperty({}, 'poisoned', {
+ get: function() {
+ throw new Test262Error();
+ }
+});
+
+assert.throws(Test262Error, function() {
+ for (const { poisoned } of [poisonedProperty]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-fn-name-arrow.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-fn-name-arrow.js
new file mode 100644
index 0000000000..a93573fbbb
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-fn-name-arrow.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-init-fn-name-arrow.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: SingleNameBinding assigns `name` to arrow functions (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ [...]
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ i. Let hasNameProperty be HasOwnProperty(v, "name").
+ ii. ReturnIfAbrupt(hasNameProperty).
+ iii. If hasNameProperty is false, perform SetFunctionName(v,
+ bindingId).
+---*/
+
+var iterCount = 0;
+
+for (const { arrow = () => {} } of [{}]) {
+ assert.sameValue(arrow.name, 'arrow');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-fn-name-class.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-fn-name-class.js
new file mode 100644
index 0000000000..a65a8562e7
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-fn-name-class.js
@@ -0,0 +1,64 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-init-fn-name-class.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: SingleNameBinding assigns `name` to "anonymous" classes (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ [...]
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ i. Let hasNameProperty be HasOwnProperty(v, "name").
+ ii. ReturnIfAbrupt(hasNameProperty).
+ iii. If hasNameProperty is false, perform SetFunctionName(v,
+ bindingId).
+---*/
+
+var iterCount = 0;
+
+for (const { cls = class {}, xCls = class X {}, xCls2 = class { static name() {} } } of [{}]) {
+ assert.sameValue(cls.name, 'cls');
+ assert.notSameValue(xCls.name, 'xCls');
+ assert.notSameValue(xCls2.name, 'xCls2');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-fn-name-cover.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-fn-name-cover.js
new file mode 100644
index 0000000000..1dbff80598
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-fn-name-cover.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-init-fn-name-cover.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: SingleNameBinding assigns `name` to "anonymous" functions "through" cover grammar (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ [...]
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ i. Let hasNameProperty be HasOwnProperty(v, "name").
+ ii. ReturnIfAbrupt(hasNameProperty).
+ iii. If hasNameProperty is false, perform SetFunctionName(v,
+ bindingId).
+---*/
+
+var iterCount = 0;
+
+for (const { cover = (function () {}), xCover = (0, function() {}) } of [{}]) {
+ assert.sameValue(cover.name, 'cover');
+ assert.notSameValue(xCover.name, 'xCover');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-fn-name-fn.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-fn-name-fn.js
new file mode 100644
index 0000000000..7113485257
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-fn-name-fn.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-init-fn-name-fn.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: SingleNameBinding assigns name to "anonymous" functions (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ [...]
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ i. Let hasNameProperty be HasOwnProperty(v, "name").
+ ii. ReturnIfAbrupt(hasNameProperty).
+ iii. If hasNameProperty is false, perform SetFunctionName(v,
+ bindingId).
+---*/
+
+var iterCount = 0;
+
+for (const { fn = function () {}, xFn = function x() {} } of [{}]) {
+ assert.sameValue(fn.name, 'fn');
+ assert.notSameValue(xFn.name, 'xFn');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-fn-name-gen.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-fn-name-gen.js
new file mode 100644
index 0000000000..71e0426536
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-fn-name-gen.js
@@ -0,0 +1,64 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-init-fn-name-gen.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: SingleNameBinding assigns name to "anonymous" generator functions (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ [...]
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ i. Let hasNameProperty be HasOwnProperty(v, "name").
+ ii. ReturnIfAbrupt(hasNameProperty).
+ iii. If hasNameProperty is false, perform SetFunctionName(v,
+ bindingId).
+
+---*/
+
+var iterCount = 0;
+
+for (const { gen = function* () {}, xGen = function* x() {} } of [{}]) {
+ assert.sameValue(gen.name, 'gen');
+ assert.notSameValue(xGen.name, 'xGen');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-skipped.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-skipped.js
new file mode 100644
index 0000000000..061901ff4d
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-skipped.js
@@ -0,0 +1,66 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-init-skipped.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Destructuring initializer is not evaluated when value is not `undefined` (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ [...]
+ [...]
+---*/
+var initCount = 0;
+function counter() {
+ initCount += 1;
+}
+
+var iterCount = 0;
+
+for (const { w = counter(), x = counter(), y = counter(), z = counter() } of [{ w: null, x: 0, y: false, z: '' }]) {
+ assert.sameValue(w, null);
+ assert.sameValue(x, 0);
+ assert.sameValue(y, false);
+ assert.sameValue(z, '');
+ assert.sameValue(initCount, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-throws.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-throws.js
new file mode 100644
index 0000000000..f1aa1a7ab3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-throws.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-init-throws.case
+// - src/dstr-binding/error/for-of-const.template
+/*---
+description: Error thrown when evaluating the initializer (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+---*/
+function thrower() {
+ throw new Test262Error();
+}
+
+assert.throws(Test262Error, function() {
+ for (const { x = thrower() } of [{}]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-unresolvable.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-unresolvable.js
new file mode 100644
index 0000000000..ee5f500377
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-init-unresolvable.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-init-unresolvable.case
+// - src/dstr-binding/error/for-of-const.template
+/*---
+description: Destructuring initializer is an unresolvable reference (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+
+ 6.2.3.1 GetValue (V)
+
+ 1. ReturnIfAbrupt(V).
+ 2. If Type(V) is not Reference, return V.
+ 3. Let base be GetBase(V).
+ 4. If IsUnresolvableReference(V), throw a ReferenceError exception.
+---*/
+
+assert.throws(ReferenceError, function() {
+ for (const { x = unresolvableReference } of [{}]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-trailing-comma.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-trailing-comma.js
new file mode 100644
index 0000000000..c3476c299f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-id-trailing-comma.js
@@ -0,0 +1,56 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-trailing-comma.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Trailing comma is allowed following BindingPropertyList (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+
+ ObjectBindingPattern[Yield] :
+ { }
+ { BindingPropertyList[?Yield] }
+ { BindingPropertyList[?Yield] , }
+---*/
+
+var iterCount = 0;
+
+for (const { x, } of [{ x: 23 }]) {
+ assert.sameValue(x, 23);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-init-err.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-init-err.js
new file mode 100644
index 0000000000..7961550941
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-init-err.js
@@ -0,0 +1,18 @@
+// |reftest| error:SyntaxError
+// Copyright (C) 2019 Aleksey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-iteration-statements
+description: >
+ Initializer is not allowed in head's ForDeclaration position.
+info: |
+ IterationStatement:
+ for (ForDeclaration of AssignmentExpression) Statement
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for (const {x} = 1 of []) {}
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-list-err.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-list-err.js
new file mode 100644
index 0000000000..6b083c1b40
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-list-err.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-list-err.case
+// - src/dstr-binding/error/for-of-const.template
+/*---
+description: Binding property list evaluation is interrupted by an abrupt completion (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.5 Runtime Semantics: BindingInitialization
+
+ BindingPropertyList : BindingPropertyList , BindingProperty
+
+ 1. Let status be the result of performing BindingInitialization for
+ BindingPropertyList using value and environment as arguments.
+ 2. ReturnIfAbrupt(status).
+---*/
+var initCount = 0;
+function thrower() {
+ throw new Test262Error();
+}
+
+assert.throws(Test262Error, function() {
+ for (const { a, b = thrower(), c = ++initCount } of [{}]) {
+ return;
+ }
+});
+
+assert.sameValue(initCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-ary-init.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-ary-init.js
new file mode 100644
index 0000000000..3070390866
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-ary-init.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-ary-init.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Object binding pattern with "nested" array binding pattern using initializer (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+ 4. Return the result of performing BindingInitialization for BindingPattern
+ passing v and environment as arguments.
+---*/
+
+var iterCount = 0;
+
+for (const { w: [x, y, z] = [4, 5, 6] } of [{}]) {
+ assert.sameValue(x, 4);
+ assert.sameValue(y, 5);
+ assert.sameValue(z, 6);
+
+ assert.throws(ReferenceError, function() {
+ w;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-ary-trailing-comma.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-ary-trailing-comma.js
new file mode 100644
index 0000000000..995d172198
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-ary-trailing-comma.js
@@ -0,0 +1,56 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-ary-trailing-comma.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Trailing comma is allowed following BindingPropertyList (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+
+ ObjectBindingPattern[Yield] :
+ { }
+ { BindingPropertyList[?Yield] }
+ { BindingPropertyList[?Yield] , }
+---*/
+
+var iterCount = 0;
+
+for (const { x: [y], } of [{ x: [45] }]) {
+ assert.sameValue(y,45);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-ary-value-null.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-ary-value-null.js
new file mode 100644
index 0000000000..7ce541e952
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-ary-value-null.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-ary-value-null.case
+// - src/dstr-binding/error/for-of-const.template
+/*---
+description: Object binding pattern with "nested" array binding pattern taking the `null` value (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ [...]
+ 4. Return the result of performing BindingInitialization for BindingPattern
+ passing v and environment as arguments.
+---*/
+
+assert.throws(TypeError, function() {
+ for (const { w: [x, y, z] = [4, 5, 6] } of [{ w: null }]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-ary.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-ary.js
new file mode 100644
index 0000000000..cadee3690e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-ary.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-ary.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Object binding pattern with "nested" array binding pattern not using initializer (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ [...]
+ 4. Return the result of performing BindingInitialization for BindingPattern
+ passing v and environment as arguments.
+---*/
+
+var iterCount = 0;
+
+for (const { w: [x, y, z] = [4, 5, 6] } of [{ w: [7, undefined, ] }]) {
+ assert.sameValue(x, 7);
+ assert.sameValue(y, undefined);
+ assert.sameValue(z, undefined);
+
+ assert.throws(ReferenceError, function() {
+ w;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-eval-err.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-eval-err.js
new file mode 100644
index 0000000000..2bf7de1950
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-eval-err.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-eval-err.case
+// - src/dstr-binding/error/for-of-const.template
+/*---
+description: Evaluation of property name returns an abrupt completion (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.5 Runtime Semantics: BindingInitialization
+
+ BindingProperty : PropertyName : BindingElement
+
+ 1. Let P be the result of evaluating PropertyName
+ 2. ReturnIfAbrupt(P).
+---*/
+function thrower() {
+ throw new Test262Error();
+}
+
+assert.throws(Test262Error, function() {
+ for (const { [thrower()]: x } of [{}]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id-get-value-err.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id-get-value-err.js
new file mode 100644
index 0000000000..31a35c2605
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id-get-value-err.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-id-get-value-err.case
+// - src/dstr-binding/error/for-of-const.template
+/*---
+description: Error thrown when accessing the corresponding property of the value object (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ BindingElement : BindingPattern Initializeropt
+
+ 1. Let v be GetV(value, propertyName).
+ 2. ReturnIfAbrupt(v).
+---*/
+var initEvalCount = 0;
+var poisonedProperty = Object.defineProperty({}, 'poisoned', {
+ get: function() {
+ throw new Test262Error();
+ }
+});
+
+assert.throws(Test262Error, function() {
+ for (const { poisoned: x = ++initEvalCount } of [poisonedProperty]) {
+ return;
+ }
+});
+
+assert.sameValue(initEvalCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id-init-skipped.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id-init-skipped.js
new file mode 100644
index 0000000000..7d22df45c2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id-init-skipped.js
@@ -0,0 +1,78 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-id-init-skipped.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Destructuring initializer is not evaluated when value is not `undefined` (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ BindingElement : BindingPattern Initializeropt
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ [...]
+---*/
+var initCount = 0;
+function counter() {
+ initCount += 1;
+}
+
+var iterCount = 0;
+
+for (const { s: t = counter(), u: v = counter(), w: x = counter(), y: z = counter() } of [{ s: null, u: 0, w: false, y: '' }]) {
+ assert.sameValue(t, null);
+ assert.sameValue(v, 0);
+ assert.sameValue(x, false);
+ assert.sameValue(z, '');
+ assert.sameValue(initCount, 0);
+
+ assert.throws(ReferenceError, function() {
+ s;
+ });
+ assert.throws(ReferenceError, function() {
+ u;
+ });
+ assert.throws(ReferenceError, function() {
+ w;
+ });
+ assert.throws(ReferenceError, function() {
+ y;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id-init-throws.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id-init-throws.js
new file mode 100644
index 0000000000..3de1ee1adf
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id-init-throws.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-id-init-throws.case
+// - src/dstr-binding/error/for-of-const.template
+/*---
+description: Error thrown when evaluating the initializer (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ BindingElement : BindingPattern Initializeropt
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+---*/
+function thrower() {
+ throw new Test262Error();
+}
+
+assert.throws(Test262Error, function() {
+ for (const { x: y = thrower() } of [{}]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id-init-unresolvable.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id-init-unresolvable.js
new file mode 100644
index 0000000000..dd9782c840
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id-init-unresolvable.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-id-init-unresolvable.case
+// - src/dstr-binding/error/for-of-const.template
+/*---
+description: Destructuring initializer is an unresolvable reference (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ BindingElement : BindingPattern Initializeropt
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+
+ 6.2.3.1 GetValue (V)
+
+ 1. ReturnIfAbrupt(V).
+ 2. If Type(V) is not Reference, return V.
+ 3. Let base be GetBase(V).
+ 4. If IsUnresolvableReference(V), throw a ReferenceError exception.
+---*/
+
+assert.throws(ReferenceError, function() {
+ for (const { x: y = unresolvableReference } of [{}]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id-init.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id-init.js
new file mode 100644
index 0000000000..1e176cc385
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id-init.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-id-init.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Binding as specified via property name, identifier, and initializer (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (const { x: y = 33 } of [{ }]) {
+ assert.sameValue(y, 33);
+ assert.throws(ReferenceError, function() {
+ x;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id-trailing-comma.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id-trailing-comma.js
new file mode 100644
index 0000000000..07c7fd9758
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id-trailing-comma.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-id-trailing-comma.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Trailing comma is allowed following BindingPropertyList (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+
+ ObjectBindingPattern[Yield] :
+ { }
+ { BindingPropertyList[?Yield] }
+ { BindingPropertyList[?Yield] , }
+---*/
+
+var iterCount = 0;
+
+for (const { x: y, } of [{ x: 23 }]) {
+ assert.sameValue(y, 23);
+
+ assert.throws(ReferenceError, function() {
+ x;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id.js
new file mode 100644
index 0000000000..b3b4e7f218
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-id.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-id.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Binding as specified via property name and identifier (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (const { x: y } of [{ x: 23 }]) {
+ assert.sameValue(y, 23);
+ assert.throws(ReferenceError, function() {
+ x;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-obj-init.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-obj-init.js
new file mode 100644
index 0000000000..8aef591cd1
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-obj-init.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-obj-init.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Object binding pattern with "nested" object binding pattern using initializer (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+ 4. Return the result of performing BindingInitialization for BindingPattern
+ passing v and environment as arguments.
+---*/
+
+var iterCount = 0;
+
+for (const { w: { x, y, z } = { x: 4, y: 5, z: 6 } } of [{ w: undefined }]) {
+ assert.sameValue(x, 4);
+ assert.sameValue(y, 5);
+ assert.sameValue(z, 6);
+
+ assert.throws(ReferenceError, function() {
+ w;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-obj-value-null.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-obj-value-null.js
new file mode 100644
index 0000000000..2cd0da6dba
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-obj-value-null.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-obj-value-null.case
+// - src/dstr-binding/error/for-of-const.template
+/*---
+description: Object binding pattern with "nested" object binding pattern taking the `null` value (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ [...]
+ 4. Return the result of performing BindingInitialization for BindingPattern
+ passing v and environment as arguments.
+---*/
+
+assert.throws(TypeError, function() {
+ for (const { w: { x, y, z } = { x: 4, y: 5, z: 6 } } of [{ w: null }]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-obj-value-undef.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-obj-value-undef.js
new file mode 100644
index 0000000000..c90a93a21b
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-obj-value-undef.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-obj-value-undef.case
+// - src/dstr-binding/error/for-of-const.template
+/*---
+description: Object binding pattern with "nested" object binding pattern taking the `null` value (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ [...]
+ 4. Return the result of performing BindingInitialization for BindingPattern
+ passing v and environment as arguments.
+---*/
+
+assert.throws(TypeError, function() {
+ for (const { w: { x, y, z } = undefined } of [{ }]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-obj.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-obj.js
new file mode 100644
index 0000000000..2c86bf1cee
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-prop-obj.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-obj.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Object binding pattern with "nested" object binding pattern not using initializer (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ [...]
+ 4. Return the result of performing BindingInitialization for BindingPattern
+ passing v and environment as arguments.
+---*/
+
+var iterCount = 0;
+
+for (const { w: { x, y, z } = { x: 4, y: 5, z: 6 } } of [{ w: { x: undefined, z: 7 } }]) {
+ assert.sameValue(x, undefined);
+ assert.sameValue(y, undefined);
+ assert.sameValue(z, 7);
+
+ assert.throws(ReferenceError, function() {
+ w;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-rest-getter.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-rest-getter.js
new file mode 100644
index 0000000000..9ab6019a31
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-rest-getter.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-rest-getter.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Getter is called when obj is being deconstructed to a rest Object (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+---*/
+var count = 0;
+
+var iterCount = 0;
+
+for (const {...x} of [{ get v() { count++; return 2; } }]) {
+ assert.sameValue(count, 1);
+
+ verifyProperty(x, "v", {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: 2
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-rest-skip-non-enumerable.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-rest-skip-non-enumerable.js
new file mode 100644
index 0000000000..15ef80cd1e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-rest-skip-non-enumerable.js
@@ -0,0 +1,66 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-rest-skip-non-enumerable.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Rest object doesn't contain non-enumerable properties (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+---*/
+var o = {a: 3, b: 4};
+Object.defineProperty(o, "x", { value: 4, enumerable: false });
+
+var iterCount = 0;
+
+for (const {...rest} of [o]) {
+ assert.sameValue(rest.x, undefined);
+
+ verifyProperty(rest, "a", {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: 3
+ });
+
+ verifyProperty(rest, "b", {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: 4
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-rest-val-obj.js b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-rest-val-obj.js
new file mode 100644
index 0000000000..69fb433326
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/const-obj-ptrn-rest-val-obj.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-rest-val-obj.case
+// - src/dstr-binding/default/for-of-const.template
+/*---
+description: Rest object contains just unextracted data (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+---*/
+
+var iterCount = 0;
+
+for (const {a, b, ...rest} of [{x: 1, y: 2, a: 5, b: 3}]) {
+ assert.sameValue(rest.a, undefined);
+ assert.sameValue(rest.b, undefined);
+
+ verifyProperty(rest, "x", {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: 1
+ });
+
+ verifyProperty(rest, "y", {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: 2
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-init-iter-close.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-init-iter-close.js
new file mode 100644
index 0000000000..9c2ba3f96c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-init-iter-close.js
@@ -0,0 +1,72 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-init-iter-close.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Iterator is closed when not exhausted by pattern evaluation (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.5 Runtime Semantics: BindingInitialization
+
+ BindingPattern : ArrayBindingPattern
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, return ? IteratorClose(iterator,
+ result).
+ [...]
+
+---*/
+var doneCallCount = 0;
+var iter = {};
+iter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { value: null, done: false };
+ },
+ return: function() {
+ doneCallCount += 1;
+ return {};
+ }
+ };
+};
+
+var iterCount = 0;
+
+for (let [x] of [iter]) {
+ assert.sameValue(doneCallCount, 1);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-init-iter-get-err-array-prototype.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-init-iter-get-err-array-prototype.js
new file mode 100644
index 0000000000..5772d2b435
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-init-iter-get-err-array-prototype.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-init-iter-get-err-array-prototype.case
+// - src/dstr-binding/error/for-of-let.template
+/*---
+description: Abrupt completion returned by GetIterator (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ Runtime Semantics: BindingInitialization
+
+ BindingPattern : ArrayBindingPattern
+
+ 1. Let iteratorRecord be ? GetIterator(value).
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ [...]
+ 4. Let iterator be ? Call(method, obj).
+
+ Call ( F, V [ , argumentsList ] )
+
+ [...]
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+
+---*/
+delete Array.prototype[Symbol.iterator];
+
+assert.throws(TypeError, function() {
+ for (let [x, y, z] of [[1, 2, 3]]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-init-iter-get-err.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-init-iter-get-err.js
new file mode 100644
index 0000000000..d67ab5c4ac
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-init-iter-get-err.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-init-iter-get-err.case
+// - src/dstr-binding/error/for-of-let.template
+/*---
+description: Abrupt completion returned by GetIterator (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.5 Runtime Semantics: BindingInitialization
+
+ BindingPattern : ArrayBindingPattern
+
+ 1. Let iterator be GetIterator(value).
+ 2. ReturnIfAbrupt(iterator).
+
+---*/
+var iter = {};
+iter[Symbol.iterator] = function() {
+ throw new Test262Error();
+};
+
+assert.throws(Test262Error, function() {
+ for (let [x] of [iter]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-init-iter-no-close.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-init-iter-no-close.js
new file mode 100644
index 0000000000..63205c97cf
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-init-iter-no-close.js
@@ -0,0 +1,72 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-init-iter-no-close.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Iterator is not closed when exhausted by pattern evaluation (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.5 Runtime Semantics: BindingInitialization
+
+ BindingPattern : ArrayBindingPattern
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, return ? IteratorClose(iterator,
+ result).
+ [...]
+
+---*/
+var doneCallCount = 0;
+var iter = {};
+iter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { value: null, done: true };
+ },
+ return: function() {
+ doneCallCount += 1;
+ return {};
+ }
+ };
+};
+
+var iterCount = 0;
+
+for (let [x] of [iter]) {
+ assert.sameValue(doneCallCount, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-name-iter-val.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-name-iter-val.js
new file mode 100644
index 0000000000..8ee75df788
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-name-iter-val.js
@@ -0,0 +1,71 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-name-iter-val.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: SingleNameBinding with normal value iteration (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (let [x, y, z] of [[1, 2, 3]]) {
+ assert.sameValue(x, 1);
+ assert.sameValue(y, 2);
+ assert.sameValue(z, 3);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-elem-init.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-elem-init.js
new file mode 100644
index 0000000000..02d52df6e6
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-elem-init.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-elem-init.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: BindingElement with array binding pattern and initializer is used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ [...]
+ 2. If iteratorRecord.[[done]] is true, let v be undefined.
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be ? GetValue(defaultValue).
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+
+var iterCount = 0;
+
+for (let [[x, y, z] = [4, 5, 6]] of [[]]) {
+ assert.sameValue(x, 4);
+ assert.sameValue(y, 5);
+ assert.sameValue(z, 6);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-elem-iter.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-elem-iter.js
new file mode 100644
index 0000000000..c6e3ff07bf
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-elem-iter.js
@@ -0,0 +1,64 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-elem-iter.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: BindingElement with array binding pattern and initializer is not used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ 1. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ [...]
+ e. Else,
+ i. Let v be IteratorValue(next).
+ [...]
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+
+var iterCount = 0;
+
+for (let [[x, y, z] = [4, 5, 6]] of [[[7, 8, 9]]]) {
+ assert.sameValue(x, 7);
+ assert.sameValue(y, 8);
+ assert.sameValue(z, 9);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-elision-init.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-elision-init.js
new file mode 100644
index 0000000000..a76de3274d
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-elision-init.js
@@ -0,0 +1,70 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-elision-init.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: BindingElement with array binding pattern and initializer is used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ [...]
+ 2. If iteratorRecord.[[done]] is true, let v be undefined.
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be ? GetValue(defaultValue).
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+
+---*/
+var first = 0;
+var second = 0;
+function* g() {
+ first += 1;
+ yield;
+ second += 1;
+};
+
+var iterCount = 0;
+
+for (let [[,] = g()] of [[]]) {
+ assert.sameValue(first, 1);
+ assert.sameValue(second, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-elision-iter.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-elision-iter.js
new file mode 100644
index 0000000000..1c62d7be26
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-elision-iter.js
@@ -0,0 +1,67 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-elision-iter.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: BindingElement with array binding pattern and initializer is not used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ 1. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ [...]
+ e. Else,
+ i. Let v be IteratorValue(next).
+ [...]
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+
+---*/
+var callCount = 0;
+function* g() {
+ callCount += 1;
+};
+
+var iterCount = 0;
+
+for (let [[,] = g()] of [[[]]]) {
+ assert.sameValue(callCount, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-empty-init.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-empty-init.js
new file mode 100644
index 0000000000..575a575b4a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-empty-init.js
@@ -0,0 +1,66 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-empty-init.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: BindingElement with array binding pattern and initializer is used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ [...]
+ 2. If iteratorRecord.[[done]] is true, let v be undefined.
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be ? GetValue(defaultValue).
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+
+---*/
+var initCount = 0;
+var iterCount = 0;
+var iter = function*() { iterCount += 1; }();
+
+var iterCount = 0;
+
+for (let [[] = function() { initCount += 1; return iter; }()] of [[]]) {
+ assert.sameValue(initCount, 1);
+ assert.sameValue(iterCount, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-empty-iter.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-empty-iter.js
new file mode 100644
index 0000000000..1494a8af29
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-empty-iter.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-empty-iter.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: BindingElement with array binding pattern and initializer is not used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ 1. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ [...]
+ e. Else,
+ i. Let v be IteratorValue(next).
+ [...]
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+var initCount = 0;
+
+var iterCount = 0;
+
+for (let [[] = function() { initCount += 1; }()] of [[[23]]]) {
+ assert.sameValue(initCount, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-rest-init.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-rest-init.js
new file mode 100644
index 0000000000..2b0e795f53
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-rest-init.js
@@ -0,0 +1,67 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-rest-init.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: BindingElement with array binding pattern and initializer is used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ [...]
+ 2. If iteratorRecord.[[done]] is true, let v be undefined.
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be ? GetValue(defaultValue).
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+var values = [2, 1, 3];
+
+var iterCount = 0;
+
+for (let [[...x] = values] of [[]]) {
+ assert(Array.isArray(x));
+ assert.sameValue(x[0], 2);
+ assert.sameValue(x[1], 1);
+ assert.sameValue(x[2], 3);
+ assert.sameValue(x.length, 3);
+ assert.notSameValue(x, values);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-rest-iter.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-rest-iter.js
new file mode 100644
index 0000000000..8fc2c4e9ad
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-rest-iter.js
@@ -0,0 +1,70 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-rest-iter.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: BindingElement with array binding pattern and initializer is not used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ 1. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ [...]
+ e. Else,
+ i. Let v be IteratorValue(next).
+ [...]
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+var values = [2, 1, 3];
+var initCount = 0;
+
+var iterCount = 0;
+
+for (let [[...x] = function() { initCount += 1; }()] of [[values]]) {
+ assert(Array.isArray(x));
+ assert.sameValue(x[0], 2);
+ assert.sameValue(x[1], 1);
+ assert.sameValue(x[2], 3);
+ assert.sameValue(x.length, 3);
+ assert.notSameValue(x, values);
+ assert.sameValue(initCount, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-val-null.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-val-null.js
new file mode 100644
index 0000000000..b012805051
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-ary-val-null.js
@@ -0,0 +1,64 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-val-null.case
+// - src/dstr-binding/error/for-of-let.template
+/*---
+description: Nested array destructuring with a null value (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPattern Initializeropt
+
+ 1. If iteratorRecord.[[done]] is false, then
+ [...]
+ e. Else
+ i. Let v be IteratorValue(next).
+ [...]
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+
+ 13.3.3.5 Runtime Semantics: BindingInitialization
+
+ BindingPattern : ArrayBindingPattern
+
+ 1. Let iterator be GetIterator(value).
+ 2. ReturnIfAbrupt(iterator).
+---*/
+
+assert.throws(TypeError, function() {
+ for (let [[x]] of [[null]]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-exhausted.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-exhausted.js
new file mode 100644
index 0000000000..73453eeff9
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-exhausted.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-exhausted.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Destructuring initializer with an exhausted iterator (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v).
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (let [x = 23] of [[]]) {
+ assert.sameValue(x, 23);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-fn-name-arrow.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-fn-name-arrow.js
new file mode 100644
index 0000000000..125d850f34
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-fn-name-arrow.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-fn-name-arrow.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: SingleNameBinding does assign name to arrow functions (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v).
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (let [arrow = () => {}] of [[]]) {
+ assert.sameValue(arrow.name, 'arrow');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-fn-name-class.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-fn-name-class.js
new file mode 100644
index 0000000000..fef2647aba
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-fn-name-class.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-fn-name-class.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: SingleNameBinding assigns `name` to "anonymous" classes (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v).
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (let [cls = class {}, xCls = class X {}, xCls2 = class { static name() {} }] of [[]]) {
+ assert.sameValue(cls.name, 'cls');
+ assert.notSameValue(xCls.name, 'xCls');
+ assert.notSameValue(xCls2.name, 'xCls2');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-fn-name-cover.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-fn-name-cover.js
new file mode 100644
index 0000000000..aa30c1fbb8
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-fn-name-cover.js
@@ -0,0 +1,64 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-fn-name-cover.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: SingleNameBinding does assign name to "anonymous" functions "through" cover grammar (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v).
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (let [cover = (function () {}), xCover = (0, function() {})] of [[]]) {
+ assert.sameValue(cover.name, 'cover');
+ assert.notSameValue(xCover.name, 'xCover');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-fn-name-fn.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-fn-name-fn.js
new file mode 100644
index 0000000000..2fd4c1c892
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-fn-name-fn.js
@@ -0,0 +1,64 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-fn-name-fn.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: SingleNameBinding assigns name to "anonymous" functions (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v).
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (let [fn = function () {}, xFn = function x() {}] of [[]]) {
+ assert.sameValue(fn.name, 'fn');
+ assert.notSameValue(xFn.name, 'xFn');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-fn-name-gen.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-fn-name-gen.js
new file mode 100644
index 0000000000..e16e291ec3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-fn-name-gen.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-fn-name-gen.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: SingleNameBinding assigns name to "anonymous" generator functions (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v).
+ 8. Return InitializeReferencedBinding(lhs, v).
+
+---*/
+
+var iterCount = 0;
+
+for (let [gen = function* () {}, xGen = function* x() {}] of [[]]) {
+ assert.sameValue(gen.name, 'gen');
+ assert.notSameValue(xGen.name, 'xGen');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-hole.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-hole.js
new file mode 100644
index 0000000000..5fda42c7d4
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-hole.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-hole.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Destructuring initializer with a "hole" (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+ SingleNameBinding : BindingIdentifier Initializeropt
+ [...] 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v). 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (let [x = 23] of [[,]]) {
+ assert.sameValue(x, 23);
+ // another statement
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-skipped.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-skipped.js
new file mode 100644
index 0000000000..a53ddf7bf4
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-skipped.js
@@ -0,0 +1,67 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-skipped.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Destructuring initializer is not evaluated when value is not `undefined` (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v).
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+var initCount = 0;
+function counter() {
+ initCount += 1;
+}
+
+var iterCount = 0;
+
+for (let [w = counter(), x = counter(), y = counter(), z = counter()] of [[null, 0, false, '']]) {
+ assert.sameValue(w, null);
+ assert.sameValue(x, 0);
+ assert.sameValue(y, false);
+ assert.sameValue(z, '');
+ assert.sameValue(initCount, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-throws.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-throws.js
new file mode 100644
index 0000000000..ddfb202e7e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-throws.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-throws.case
+// - src/dstr-binding/error/for-of-let.template
+/*---
+description: Destructuring initializer returns an abrupt completion (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+---*/
+
+assert.throws(Test262Error, function() {
+ for (let [x = (function() { throw new Test262Error(); })()] of [[undefined]]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-undef.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-undef.js
new file mode 100644
index 0000000000..d7db6260ed
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-undef.js
@@ -0,0 +1,61 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-undef.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Destructuring initializer with an undefined value (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v).
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (let [x = 23] of [[undefined]]) {
+ assert.sameValue(x, 23);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-unresolvable.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-unresolvable.js
new file mode 100644
index 0000000000..77e2bb144a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-unresolvable.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-unresolvable.case
+// - src/dstr-binding/error/for-of-let.template
+/*---
+description: Destructuring initializer is an unresolvable reference (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+
+ 6.2.3.1 GetValue (V)
+
+ 1. ReturnIfAbrupt(V).
+ 2. If Type(V) is not Reference, return V.
+ 3. Let base be GetBase(V).
+ 4. If IsUnresolvableReference(V), throw a ReferenceError exception.
+---*/
+
+assert.throws(ReferenceError, function() {
+ for (let [ x = unresolvableReference ] of [[]]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-iter-complete.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-iter-complete.js
new file mode 100644
index 0000000000..c3066148f9
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-iter-complete.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-iter-complete.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: SingleNameBinding when value iteration completes (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (let [x] of [[]]) {
+ assert.sameValue(x, undefined);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-iter-done.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-iter-done.js
new file mode 100644
index 0000000000..b60398b7fe
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-iter-done.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-iter-done.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: SingleNameBinding when value iteration was completed previously (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ [...]
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (let [_, x] of [[]]) {
+ assert.sameValue(x, undefined);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-iter-step-err.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-iter-step-err.js
new file mode 100644
index 0000000000..20cd863ab3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-iter-step-err.js
@@ -0,0 +1,64 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-iter-step-err.case
+// - src/dstr-binding/error/for-of-let.template
+/*---
+description: Error forwarding when IteratorStep returns an abrupt completion (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+
+---*/
+var g = {};
+g[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ throw new Test262Error();
+ }
+ };
+};
+
+assert.throws(Test262Error, function() {
+ for (let [x] of [g]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-iter-val-array-prototype.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-iter-val-array-prototype.js
new file mode 100644
index 0000000000..968f027b96
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-iter-val-array-prototype.js
@@ -0,0 +1,81 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-iter-val-array-prototype.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Array destructuring uses overriden Array.prototype[Symbol.iterator] (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializer_opt
+
+ 1. Let bindingId be StringValue of BindingIdentifier.
+ 2. Let lhs be ? ResolveBinding(bindingId, environment).
+ 3. If iteratorRecord.[[Done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord).
+ b. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[Done]] to true.
+ e. Else,
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ iii. ReturnIfAbrupt(v).
+ [...]
+ 7. Return InitializeReferencedBinding(lhs, v).
+
+---*/
+Array.prototype[Symbol.iterator] = function* () {
+ if (this.length > 0) {
+ yield this[0];
+ }
+ if (this.length > 1) {
+ yield this[1];
+ }
+ if (this.length > 2) {
+ yield 42;
+ }
+};
+
+var iterCount = 0;
+
+for (let [x, y, z] of [[1, 2, 3]]) {
+ assert.sameValue(x, 1);
+ assert.sameValue(y, 2);
+ assert.sameValue(z, 42);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-iter-val-err.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-iter-val-err.js
new file mode 100644
index 0000000000..744627718e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-iter-val-err.js
@@ -0,0 +1,75 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-iter-val-err.case
+// - src/dstr-binding/error/for-of-let.template
+/*---
+description: Error forwarding when IteratorValue returns an abrupt completion (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set iteratorRecord.[[done]] to
+ true.
+ iii. ReturnIfAbrupt(v).
+
+---*/
+var poisonedValue = Object.defineProperty({}, 'value', {
+ get: function() {
+ throw new Test262Error();
+ }
+});
+var g = {};
+g[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return poisonedValue;
+ }
+ };
+};
+
+assert.throws(Test262Error, function() {
+ for (let [x] of [g]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-iter-val.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-iter-val.js
new file mode 100644
index 0000000000..ecd94ba119
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-id-iter-val.js
@@ -0,0 +1,71 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-iter-val.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: SingleNameBinding when value iteration was completed previously (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (let [x, y, z] of [[1, 2, 3]]) {
+ assert.sameValue(x, 1);
+ assert.sameValue(y, 2);
+ assert.sameValue(z, 3);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-obj-id-init.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-obj-id-init.js
new file mode 100644
index 0000000000..d345996ea4
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-obj-id-init.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-obj-id-init.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: BindingElement with object binding pattern and initializer is used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ [...]
+ 2. If iteratorRecord.[[done]] is true, let v be undefined.
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be ? GetValue(defaultValue).
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+
+var iterCount = 0;
+
+for (let [{ x, y, z } = { x: 44, y: 55, z: 66 }] of [[]]) {
+ assert.sameValue(x, 44);
+ assert.sameValue(y, 55);
+ assert.sameValue(z, 66);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-obj-id.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-obj-id.js
new file mode 100644
index 0000000000..086b9871ee
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-obj-id.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-obj-id.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: BindingElement with object binding pattern and initializer is not used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ [...]
+ 2. If iteratorRecord.[[done]] is true, let v be undefined.
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be ? GetValue(defaultValue).
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+
+var iterCount = 0;
+
+for (let [{ x, y, z } = { x: 44, y: 55, z: 66 }] of [[{ x: 11, y: 22, z: 33 }]]) {
+ assert.sameValue(x, 11);
+ assert.sameValue(y, 22);
+ assert.sameValue(z, 33);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-obj-prop-id-init.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-obj-prop-id-init.js
new file mode 100644
index 0000000000..37e59ddd46
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-obj-prop-id-init.js
@@ -0,0 +1,73 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-obj-prop-id-init.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: BindingElement with object binding pattern and initializer is used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ [...]
+ 2. If iteratorRecord.[[done]] is true, let v be undefined.
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be ? GetValue(defaultValue).
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+
+var iterCount = 0;
+
+for (let [{ u: v, w: x, y: z } = { u: 444, w: 555, y: 666 }] of [[]]) {
+ assert.sameValue(v, 444);
+ assert.sameValue(x, 555);
+ assert.sameValue(z, 666);
+
+ assert.throws(ReferenceError, function() {
+ u;
+ });
+ assert.throws(ReferenceError, function() {
+ w;
+ });
+ assert.throws(ReferenceError, function() {
+ y;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-obj-prop-id.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-obj-prop-id.js
new file mode 100644
index 0000000000..8bc6b1a244
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-obj-prop-id.js
@@ -0,0 +1,73 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-obj-prop-id.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: BindingElement with object binding pattern and initializer is not used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ [...]
+ 2. If iteratorRecord.[[done]] is true, let v be undefined.
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be ? GetValue(defaultValue).
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+
+var iterCount = 0;
+
+for (let [{ u: v, w: x, y: z } = { u: 444, w: 555, y: 666 }] of [[{ u: 777, w: 888, y: 999 }]]) {
+ assert.sameValue(v, 777);
+ assert.sameValue(x, 888);
+ assert.sameValue(z, 999);
+
+ assert.throws(ReferenceError, function() {
+ u;
+ });
+ assert.throws(ReferenceError, function() {
+ w;
+ });
+ assert.throws(ReferenceError, function() {
+ y;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-obj-val-null.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-obj-val-null.js
new file mode 100644
index 0000000000..a52a1db344
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-obj-val-null.js
@@ -0,0 +1,64 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-obj-val-null.case
+// - src/dstr-binding/error/for-of-let.template
+/*---
+description: Nested object destructuring with a null value (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPattern Initializeropt
+
+ 1. If iteratorRecord.[[done]] is false, then
+ [...]
+ e. Else
+ i. Let v be IteratorValue(next).
+ [...]
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+
+ 13.3.3.5 Runtime Semantics: BindingInitialization
+
+ BindingPattern : ObjectBindingPattern
+
+ 1. Let valid be RequireObjectCoercible(value).
+ 2. ReturnIfAbrupt(valid).
+---*/
+
+assert.throws(TypeError, function() {
+ for (let [{ x }] of [[null]]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-obj-val-undef.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-obj-val-undef.js
new file mode 100644
index 0000000000..3daea7a5f7
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elem-obj-val-undef.js
@@ -0,0 +1,64 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-obj-val-undef.case
+// - src/dstr-binding/error/for-of-let.template
+/*---
+description: Nested object destructuring with a value of `undefined` (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPattern Initializeropt
+
+ 1. If iteratorRecord.[[done]] is false, then
+ [...]
+ e. Else
+ i. Let v be IteratorValue(next).
+ [...]
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+
+ 13.3.3.5 Runtime Semantics: BindingInitialization
+
+ BindingPattern : ObjectBindingPattern
+
+ 1. Let valid be RequireObjectCoercible(value).
+ 2. ReturnIfAbrupt(valid).
+---*/
+
+assert.throws(TypeError, function() {
+ for (let [{ x }] of [[]]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elision-exhausted.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elision-exhausted.js
new file mode 100644
index 0000000000..4d467bf91c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elision-exhausted.js
@@ -0,0 +1,68 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elision-exhausted.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Elision accepts exhausted iterator (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ ArrayBindingPattern : [ Elision ]
+
+ 1. Return the result of performing
+ IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord
+ as the argument.
+
+ 12.14.5.3 Runtime Semantics: IteratorDestructuringAssignmentEvaluation
+
+ Elision : ,
+
+ 1. If iteratorRecord.[[done]] is false, then
+ [...]
+ 2. Return NormalCompletion(empty).
+
+---*/
+var iter = function*() {}();
+iter.next();
+
+var iterCount = 0;
+
+for (let [,] of [iter]) {
+
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elision-iter-close.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elision-iter-close.js
new file mode 100644
index 0000000000..5eaef08293
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elision-iter-close.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elision-iter-close.case
+// - src/dstr-binding/iter-close/for-of-let.template
+/*---
+description: The iterator is properly consumed by the destructuring pattern (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+---*/
+const iter = (function* () {
+ yield;
+ yield;
+})();
+
+
+function fn() {
+ for (let [,] of [iter]) {
+ return;
+ }
+}
+
+fn();
+
+assert.sameValue(iter.next().done, true, 'iteration occurred as expected');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elision-step-err.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elision-step-err.js
new file mode 100644
index 0000000000..476262dc7d
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elision-step-err.js
@@ -0,0 +1,71 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elision-step-err.case
+// - src/dstr-binding/error/for-of-let.template
+/*---
+description: Elision advances iterator and forwards abrupt completions (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ ArrayBindingPattern : [ Elision ]
+
+ 1. Return the result of performing
+ IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord
+ as the argument.
+
+ 12.14.5.3 Runtime Semantics: IteratorDestructuringAssignmentEvaluation
+
+ Elision : ,
+
+ 1. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+
+---*/
+var following = 0;
+var iter =function* () {
+ throw new Test262Error();
+ following += 1;
+}();
+
+assert.throws(Test262Error, function() {
+ for (let [,] of [iter]) {
+ return;
+ }
+});
+
+iter.next();
+assert.sameValue(following, 0, 'Iterator was properly closed.');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elision.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elision.js
new file mode 100644
index 0000000000..afa835f0d6
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-elision.js
@@ -0,0 +1,77 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elision.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Elision advances iterator (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ ArrayBindingPattern : [ Elision ]
+
+ 1. Return the result of performing
+ IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord
+ as the argument.
+
+ 12.14.5.3 Runtime Semantics: IteratorDestructuringAssignmentEvaluation
+
+ Elision : ,
+
+ 1. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ 2. Return NormalCompletion(empty).
+
+---*/
+var first = 0;
+var second = 0;
+function* g() {
+ first += 1;
+ yield;
+ second += 1;
+};
+
+var iterCount = 0;
+
+for (let [,] of [g()]) {
+ assert.sameValue(first, 1);
+ assert.sameValue(second, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-empty.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-empty.js
new file mode 100644
index 0000000000..66d7a0fe4a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-empty.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-empty.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: No iteration occurs for an "empty" array binding pattern (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ ArrayBindingPattern : [ ]
+
+ 1. Return NormalCompletion(empty).
+
+---*/
+var iterations = 0;
+var iter = function*() {
+ iterations += 1;
+}();
+
+var iterCount = 0;
+
+for (let [] of [iter]) {
+ assert.sameValue(iterations, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-init-err.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-init-err.js
new file mode 100644
index 0000000000..9c9f86e19e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-init-err.js
@@ -0,0 +1,18 @@
+// |reftest| error:SyntaxError
+// Copyright (C) 2019 Aleksey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-iteration-statements
+description: >
+ Initializer is not allowed in head's ForDeclaration position.
+info: |
+ IterationStatement:
+ for (ForDeclaration of AssignmentExpression) Statement
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for (let [x] = 1 of []) {}
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-ary-elem.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-ary-elem.js
new file mode 100644
index 0000000000..2f03e1f2a6
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-ary-elem.js
@@ -0,0 +1,84 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-ary-elem.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Rest element containing an array BindingElementList pattern (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingRestElement : ... BindingPattern
+
+ 1. Let A be ArrayCreate(0).
+ [...]
+ 3. Repeat
+ [...]
+ b. If iteratorRecord.[[done]] is true, then
+ i. Return the result of performing BindingInitialization of
+ BindingPattern with A and environment as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (let [...[x, y, z]] of [[3, 4, 5]]) {
+ assert.sameValue(x, 3);
+ assert.sameValue(y, 4);
+ assert.sameValue(z, 5);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-ary-elision.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-ary-elision.js
new file mode 100644
index 0000000000..d9d1f9e3bd
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-ary-elision.js
@@ -0,0 +1,90 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-ary-elision.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Rest element containing an elision (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingRestElement : ... BindingPattern
+
+ 1. Let A be ArrayCreate(0).
+ [...]
+ 3. Repeat
+ [...]
+ b. If iteratorRecord.[[done]] is true, then
+ i. Return the result of performing BindingInitialization of
+ BindingPattern with A and environment as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ ArrayBindingPattern : [ Elision ]
+
+ 1. Return the result of performing
+ IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord
+ as the argument.
+
+ 12.14.5.3 Runtime Semantics: IteratorDestructuringAssignmentEvaluation
+
+ Elision : ,
+
+ 1. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ 2. Return NormalCompletion(empty).
+
+---*/
+var first = 0;
+var second = 0;
+function* g() {
+ first += 1;
+ yield;
+ second += 1;
+};
+
+var iterCount = 0;
+
+for (let [...[,]] of [g()]) {
+ assert.sameValue(first, 1);
+ assert.sameValue(second, 1);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-ary-empty.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-ary-empty.js
new file mode 100644
index 0000000000..dea5af639f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-ary-empty.js
@@ -0,0 +1,73 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-ary-empty.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Rest element containing an "empty" array pattern (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingRestElement : ... BindingPattern
+
+ 1. Let A be ArrayCreate(0).
+ [...]
+ 3. Repeat
+ [...]
+ b. If iteratorRecord.[[done]] is true, then
+ i. Return the result of performing BindingInitialization of
+ BindingPattern with A and environment as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ ArrayBindingPattern : [ ]
+
+ 1. Return NormalCompletion(empty).
+
+---*/
+var iterations = 0;
+var iter = function*() {
+ iterations += 1;
+}();
+
+var iterCount = 0;
+
+for (let [...[]] of [iter]) {
+ assert.sameValue(iterations, 1);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-ary-rest.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-ary-rest.js
new file mode 100644
index 0000000000..09def53f88
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-ary-rest.js
@@ -0,0 +1,69 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-ary-rest.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Rest element containing a rest element (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingRestElement : ... BindingPattern
+
+ 1. Let A be ArrayCreate(0).
+ [...]
+ 3. Repeat
+ [...]
+ b. If iteratorRecord.[[done]] is true, then
+ i. Return the result of performing BindingInitialization of
+ BindingPattern with A and environment as the arguments.
+ [...]
+---*/
+var values = [1, 2, 3];
+
+var iterCount = 0;
+
+for (let [...[...x]] of [values]) {
+ assert(Array.isArray(x));
+ assert.sameValue(x.length, 3);
+ assert.sameValue(x[0], 1);
+ assert.sameValue(x[1], 2);
+ assert.sameValue(x[2], 3);
+ assert.notSameValue(x, values);
+
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-direct.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-direct.js
new file mode 100644
index 0000000000..4b1b9723f2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-direct.js
@@ -0,0 +1,64 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-id-direct.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Lone rest element (direct binding) (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+includes: [compareArray.js]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ Runtime Semantics: IteratorBindingInitialization
+
+ BindingRestElement : ... BindingIdentifier
+
+ [...]
+ 2. Let A be ! ArrayCreate(0).
+ 3. Let n be 0.
+ 4. Repeat,
+ [...]
+ f. Perform ! CreateDataPropertyOrThrow(A, ! ToString(n), nextValue).
+ g. Set n to n + 1.
+
+---*/
+
+var iterCount = 0;
+
+for (let [...x] of [[1]]) {
+ assert(Array.isArray(x));
+ assert.compareArray(x, [1]);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-elision-next-err.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-elision-next-err.js
new file mode 100644
index 0000000000..b4ebb84303
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-elision-next-err.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-id-elision-next-err.case
+// - src/dstr-binding/error/for-of-let.template
+/*---
+description: Rest element following elision elements (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+ ArrayBindingPattern : [ Elisionopt BindingRestElement ]
+ 1. If Elision is present, then
+ a. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of Elision with
+ iteratorRecord as the argument.
+ b. ReturnIfAbrupt(status).
+ 2. Return the result of performing IteratorBindingInitialization for
+ BindingRestElement with iteratorRecord and environment as arguments.
+
+---*/
+var iter = (function*() { throw new Test262Error(); })();
+
+assert.throws(Test262Error, function() {
+ for (let [, ...x] of [iter]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-elision.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-elision.js
new file mode 100644
index 0000000000..56ec257ce5
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-elision.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-id-elision.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Rest element following elision elements (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+ ArrayBindingPattern : [ Elisionopt BindingRestElement ]
+ 1. If Elision is present, then
+ a. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of Elision with
+ iteratorRecord as the argument.
+ b. ReturnIfAbrupt(status).
+ 2. Return the result of performing IteratorBindingInitialization for
+ BindingRestElement with iteratorRecord and environment as arguments.
+---*/
+var values = [1, 2, 3, 4, 5];
+
+var iterCount = 0;
+
+for (let [ , , ...x] of [values]) {
+ assert(Array.isArray(x));
+ assert.sameValue(x.length, 3);
+ assert.sameValue(x[0], 3);
+ assert.sameValue(x[1], 4);
+ assert.sameValue(x[2], 5);
+ assert.notSameValue(x, values);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-exhausted.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-exhausted.js
new file mode 100644
index 0000000000..c3c190675e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-exhausted.js
@@ -0,0 +1,61 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-id-exhausted.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: RestElement applied to an exhausted iterator (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+ BindingRestElement : ... BindingIdentifier
+ 1. Let lhs be ResolveBinding(StringValue of BindingIdentifier,
+ environment).
+ 2. ReturnIfAbrupt(lhs). 3. Let A be ArrayCreate(0). 4. Let n=0. 5. Repeat,
+ [...]
+ b. If iteratorRecord.[[done]] is true, then
+ i. If environment is undefined, return PutValue(lhs, A).
+ ii. Return InitializeReferencedBinding(lhs, A).
+
+---*/
+
+var iterCount = 0;
+
+for (let [, , ...x] of [[1, 2]]) {
+ assert(Array.isArray(x));
+ assert.sameValue(x.length, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-iter-close.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-iter-close.js
new file mode 100644
index 0000000000..ca6f9b1edd
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-iter-close.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-id-iter-close.case
+// - src/dstr-binding/iter-close/for-of-let.template
+/*---
+description: The iterator is properly consumed by the destructuring pattern (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+---*/
+const iter = (function* () {
+ yield;
+ yield;
+})();
+
+
+function fn() {
+ for (let [...x] of [iter]) {
+ return;
+ }
+}
+
+fn();
+
+assert.sameValue(iter.next().done, true, 'iteration occurred as expected');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-iter-step-err.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-iter-step-err.js
new file mode 100644
index 0000000000..da0f4ff5ef
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-iter-step-err.js
@@ -0,0 +1,68 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-id-iter-step-err.case
+// - src/dstr-binding/error/for-of-let.template
+/*---
+description: Error forwarding when IteratorStep returns an abrupt completion (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+ BindingRestElement : ... BindingIdentifier
+ 1. Let lhs be ResolveBinding(StringValue of BindingIdentifier,
+ environment).
+ 2. ReturnIfAbrupt(lhs). 3. Let A be ArrayCreate(0). 4. Let n=0. 5. Repeat,
+ a. If iteratorRecord.[[done]] is false,
+ i. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ ii. If next is an abrupt completion, set iteratorRecord.[[done]] to
+ true.
+ iii. ReturnIfAbrupt(next).
+
+---*/
+var first = 0;
+var second = 0;
+var iter = function*() {
+ first += 1;
+ throw new Test262Error();
+ second += 1;
+}();
+
+assert.throws(Test262Error, function() {
+ for (let [...x] of [iter]) {
+ return;
+ }
+});
+
+iter.next();
+assert.sameValue(first, 1);
+assert.sameValue(second, 0, 'Iterator is closed following abrupt completion.');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-iter-val-err.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-iter-val-err.js
new file mode 100644
index 0000000000..e61fdcb66a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id-iter-val-err.js
@@ -0,0 +1,70 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-id-iter-val-err.case
+// - src/dstr-binding/error/for-of-let.template
+/*---
+description: Error forwarding when IteratorValue returns an abrupt completion (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+ BindingRestElement : ... BindingIdentifier
+ 1. Let lhs be ResolveBinding(StringValue of BindingIdentifier,
+ environment).
+ 2. ReturnIfAbrupt(lhs). 3. Let A be ArrayCreate(0). 4. Let n=0. 5. Repeat,
+ [...]
+ c. Let nextValue be IteratorValue(next).
+ d. If nextValue is an abrupt completion, set iteratorRecord.[[done]] to
+ true.
+ e. ReturnIfAbrupt(nextValue).
+
+---*/
+var poisonedValue = Object.defineProperty({}, 'value', {
+ get: function() {
+ throw new Test262Error();
+ }
+});
+var iter = {};
+iter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return poisonedValue;
+ }
+ };
+};
+
+assert.throws(Test262Error, function() {
+ for (let [...x] of [iter]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id.js
new file mode 100644
index 0000000000..ef1bc67f10
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-id.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-id.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Lone rest element (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+ BindingRestElement : ... BindingIdentifier
+ [...] 3. Let A be ArrayCreate(0). [...] 5. Repeat
+ [...]
+ f. Let status be CreateDataProperty(A, ToString (n), nextValue).
+ [...]
+---*/
+var values = [1, 2, 3];
+
+var iterCount = 0;
+
+for (let [...x] of [values]) {
+ assert(Array.isArray(x));
+ assert.sameValue(x.length, 3);
+ assert.sameValue(x[0], 1);
+ assert.sameValue(x[1], 2);
+ assert.sameValue(x[2], 3);
+ assert.notSameValue(x, values);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-init-ary.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-init-ary.js
new file mode 100644
index 0000000000..dbd5d76f0f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-init-ary.js
@@ -0,0 +1,58 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-init-ary.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Rest element (nested array pattern) does not support initializer (for-of 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 ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+ ArrayBindingPattern[Yield] :
+ [ Elisionopt BindingRestElement[?Yield]opt ]
+ [ BindingElementList[?Yield] ]
+ [ BindingElementList[?Yield] , Elisionopt BindingRestElement[?Yield]opt ]
+---*/
+$DONOTEVALUATE();
+
+var iterCount = 0;
+
+for (let [...[ x ] = []] of [[]]) {
+
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-init-id.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-init-id.js
new file mode 100644
index 0000000000..c4cdff33ae
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-init-id.js
@@ -0,0 +1,58 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-init-id.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Rest element (identifier) does not support initializer (for-of 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 ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+ ArrayBindingPattern[Yield] :
+ [ Elisionopt BindingRestElement[?Yield]opt ]
+ [ BindingElementList[?Yield] ]
+ [ BindingElementList[?Yield] , Elisionopt BindingRestElement[?Yield]opt ]
+---*/
+$DONOTEVALUATE();
+
+var iterCount = 0;
+
+for (let [...x = []] of [[]]) {
+
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-init-obj.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-init-obj.js
new file mode 100644
index 0000000000..1ab019d9ae
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-init-obj.js
@@ -0,0 +1,58 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-init-obj.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Rest element (nested object pattern) does not support initializer (for-of 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 ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+ ArrayBindingPattern[Yield] :
+ [ Elisionopt BindingRestElement[?Yield]opt ]
+ [ BindingElementList[?Yield] ]
+ [ BindingElementList[?Yield] , Elisionopt BindingRestElement[?Yield]opt ]
+---*/
+$DONOTEVALUATE();
+
+var iterCount = 0;
+
+for (let [...{ x } = []] of [[]]) {
+
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-not-final-ary.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-not-final-ary.js
new file mode 100644
index 0000000000..5e254fd3fb
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-not-final-ary.js
@@ -0,0 +1,58 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-not-final-ary.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Rest element (array binding pattern) may not be followed by any element (for-of 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 ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+ ArrayBindingPattern[Yield] :
+ [ Elisionopt BindingRestElement[?Yield]opt ]
+ [ BindingElementList[?Yield] ]
+ [ BindingElementList[?Yield] , Elisionopt BindingRestElement[?Yield]opt ]
+---*/
+$DONOTEVALUATE();
+
+var iterCount = 0;
+
+for (let [...[x], y] of [[1, 2, 3]]) {
+
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-not-final-id.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-not-final-id.js
new file mode 100644
index 0000000000..81967123ec
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-not-final-id.js
@@ -0,0 +1,58 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-not-final-id.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Rest element (identifier) may not be followed by any element (for-of 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 ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+ ArrayBindingPattern[Yield] :
+ [ Elisionopt BindingRestElement[?Yield]opt ]
+ [ BindingElementList[?Yield] ]
+ [ BindingElementList[?Yield] , Elisionopt BindingRestElement[?Yield]opt ]
+---*/
+$DONOTEVALUATE();
+
+var iterCount = 0;
+
+for (let [...x, y] of [[1, 2, 3]]) {
+
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-not-final-obj.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-not-final-obj.js
new file mode 100644
index 0000000000..b744247852
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-not-final-obj.js
@@ -0,0 +1,58 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-not-final-obj.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Rest element (object binding pattern) may not be followed by any element (for-of 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 ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+ ArrayBindingPattern[Yield] :
+ [ Elisionopt BindingRestElement[?Yield]opt ]
+ [ BindingElementList[?Yield] ]
+ [ BindingElementList[?Yield] , Elisionopt BindingRestElement[?Yield]opt ]
+---*/
+$DONOTEVALUATE();
+
+var iterCount = 0;
+
+for (let [...{ x }, y] of [[1, 2, 3]]) {
+
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-obj-id.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-obj-id.js
new file mode 100644
index 0000000000..982ddef1a4
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-obj-id.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-obj-id.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Rest element containing an object binding pattern (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingRestElement : ... BindingPattern
+
+ 1. Let A be ArrayCreate(0).
+ [...]
+ 3. Repeat
+ [...]
+ b. If iteratorRecord.[[done]] is true, then
+ i. Return the result of performing BindingInitialization of
+ BindingPattern with A and environment as the arguments.
+ [...]
+---*/
+
+var iterCount = 0;
+
+for (let [...{ length }] of [[1, 2, 3]]) {
+ assert.sameValue(length, 3);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-obj-prop-id.js b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-obj-prop-id.js
new file mode 100644
index 0000000000..20a9e2c9f4
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-ary-ptrn-rest-obj-prop-id.js
@@ -0,0 +1,69 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-obj-prop-id.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Rest element containing an object binding pattern (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingRestElement : ... BindingPattern
+
+ 1. Let A be ArrayCreate(0).
+ [...]
+ 3. Repeat
+ [...]
+ b. If iteratorRecord.[[done]] is true, then
+ i. Return the result of performing BindingInitialization of
+ BindingPattern with A and environment as the arguments.
+ [...]
+---*/
+let length = "outer";
+
+var iterCount = 0;
+
+for (let [...{ 0: v, 1: w, 2: x, 3: y, length: z }] of [[7, 8, 9]]) {
+ assert.sameValue(v, 7);
+ assert.sameValue(w, 8);
+ assert.sameValue(x, 9);
+ assert.sameValue(y, undefined);
+ assert.sameValue(z, 3);
+
+ assert.sameValue(length, "outer", "the length prop is not set as a binding name");
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-init-null.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-init-null.js
new file mode 100644
index 0000000000..8a8a72b0d2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-init-null.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-init-null.case
+// - src/dstr-binding/error/for-of-let.template
+/*---
+description: Value specifed for object binding pattern must be object coercible (null) (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ Runtime Semantics: BindingInitialization
+
+ ObjectBindingPattern : { }
+
+ 1. Return NormalCompletion(empty).
+---*/
+
+assert.throws(TypeError, function() {
+ for (let {} of [null]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-init-undefined.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-init-undefined.js
new file mode 100644
index 0000000000..748dede704
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-init-undefined.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-init-undefined.case
+// - src/dstr-binding/error/for-of-let.template
+/*---
+description: Value specifed for object binding pattern must be object coercible (undefined) (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ Runtime Semantics: BindingInitialization
+
+ ObjectBindingPattern : { }
+
+ 1. Return NormalCompletion(empty).
+---*/
+
+assert.throws(TypeError, function() {
+ for (let {} of [undefined]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-empty.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-empty.js
new file mode 100644
index 0000000000..85c41d7cc9
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-empty.js
@@ -0,0 +1,61 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-empty.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: No property access occurs for an "empty" object binding pattern (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ Runtime Semantics: BindingInitialization
+
+ ObjectBindingPattern : { }
+
+ 1. Return NormalCompletion(empty).
+---*/
+var accessCount = 0;
+var obj = Object.defineProperty({}, 'attr', {
+ get: function() {
+ accessCount += 1;
+ }
+});
+
+var iterCount = 0;
+
+for (let {} of [obj]) {
+ assert.sameValue(accessCount, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-get-value-err.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-get-value-err.js
new file mode 100644
index 0000000000..fb046302fc
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-get-value-err.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-get-value-err.case
+// - src/dstr-binding/error/for-of-let.template
+/*---
+description: Error thrown when accessing the corresponding property of the value object (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. Let v be GetV(value, propertyName).
+ 5. ReturnIfAbrupt(v).
+---*/
+var poisonedProperty = Object.defineProperty({}, 'poisoned', {
+ get: function() {
+ throw new Test262Error();
+ }
+});
+
+assert.throws(Test262Error, function() {
+ for (let { poisoned } of [poisonedProperty]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-fn-name-arrow.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-fn-name-arrow.js
new file mode 100644
index 0000000000..d638a5f92f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-fn-name-arrow.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-init-fn-name-arrow.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: SingleNameBinding assigns `name` to arrow functions (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ [...]
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ i. Let hasNameProperty be HasOwnProperty(v, "name").
+ ii. ReturnIfAbrupt(hasNameProperty).
+ iii. If hasNameProperty is false, perform SetFunctionName(v,
+ bindingId).
+---*/
+
+var iterCount = 0;
+
+for (let { arrow = () => {} } of [{}]) {
+ assert.sameValue(arrow.name, 'arrow');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-fn-name-class.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-fn-name-class.js
new file mode 100644
index 0000000000..c801ccd4be
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-fn-name-class.js
@@ -0,0 +1,64 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-init-fn-name-class.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: SingleNameBinding assigns `name` to "anonymous" classes (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ [...]
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ i. Let hasNameProperty be HasOwnProperty(v, "name").
+ ii. ReturnIfAbrupt(hasNameProperty).
+ iii. If hasNameProperty is false, perform SetFunctionName(v,
+ bindingId).
+---*/
+
+var iterCount = 0;
+
+for (let { cls = class {}, xCls = class X {}, xCls2 = class { static name() {} } } of [{}]) {
+ assert.sameValue(cls.name, 'cls');
+ assert.notSameValue(xCls.name, 'xCls');
+ assert.notSameValue(xCls2.name, 'xCls2');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-fn-name-cover.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-fn-name-cover.js
new file mode 100644
index 0000000000..5261c6c37c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-fn-name-cover.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-init-fn-name-cover.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: SingleNameBinding assigns `name` to "anonymous" functions "through" cover grammar (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ [...]
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ i. Let hasNameProperty be HasOwnProperty(v, "name").
+ ii. ReturnIfAbrupt(hasNameProperty).
+ iii. If hasNameProperty is false, perform SetFunctionName(v,
+ bindingId).
+---*/
+
+var iterCount = 0;
+
+for (let { cover = (function () {}), xCover = (0, function() {}) } of [{}]) {
+ assert.sameValue(cover.name, 'cover');
+ assert.notSameValue(xCover.name, 'xCover');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-fn-name-fn.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-fn-name-fn.js
new file mode 100644
index 0000000000..37ffb46c55
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-fn-name-fn.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-init-fn-name-fn.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: SingleNameBinding assigns name to "anonymous" functions (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ [...]
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ i. Let hasNameProperty be HasOwnProperty(v, "name").
+ ii. ReturnIfAbrupt(hasNameProperty).
+ iii. If hasNameProperty is false, perform SetFunctionName(v,
+ bindingId).
+---*/
+
+var iterCount = 0;
+
+for (let { fn = function () {}, xFn = function x() {} } of [{}]) {
+ assert.sameValue(fn.name, 'fn');
+ assert.notSameValue(xFn.name, 'xFn');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-fn-name-gen.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-fn-name-gen.js
new file mode 100644
index 0000000000..f2e81e9467
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-fn-name-gen.js
@@ -0,0 +1,64 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-init-fn-name-gen.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: SingleNameBinding assigns name to "anonymous" generator functions (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ [...]
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ i. Let hasNameProperty be HasOwnProperty(v, "name").
+ ii. ReturnIfAbrupt(hasNameProperty).
+ iii. If hasNameProperty is false, perform SetFunctionName(v,
+ bindingId).
+
+---*/
+
+var iterCount = 0;
+
+for (let { gen = function* () {}, xGen = function* x() {} } of [{}]) {
+ assert.sameValue(gen.name, 'gen');
+ assert.notSameValue(xGen.name, 'xGen');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-skipped.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-skipped.js
new file mode 100644
index 0000000000..3d7a799f73
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-skipped.js
@@ -0,0 +1,66 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-init-skipped.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Destructuring initializer is not evaluated when value is not `undefined` (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ [...]
+ [...]
+---*/
+var initCount = 0;
+function counter() {
+ initCount += 1;
+}
+
+var iterCount = 0;
+
+for (let { w = counter(), x = counter(), y = counter(), z = counter() } of [{ w: null, x: 0, y: false, z: '' }]) {
+ assert.sameValue(w, null);
+ assert.sameValue(x, 0);
+ assert.sameValue(y, false);
+ assert.sameValue(z, '');
+ assert.sameValue(initCount, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-throws.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-throws.js
new file mode 100644
index 0000000000..879f9cb43a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-throws.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-init-throws.case
+// - src/dstr-binding/error/for-of-let.template
+/*---
+description: Error thrown when evaluating the initializer (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+---*/
+function thrower() {
+ throw new Test262Error();
+}
+
+assert.throws(Test262Error, function() {
+ for (let { x = thrower() } of [{}]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-unresolvable.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-unresolvable.js
new file mode 100644
index 0000000000..a58d6660e3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-init-unresolvable.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-init-unresolvable.case
+// - src/dstr-binding/error/for-of-let.template
+/*---
+description: Destructuring initializer is an unresolvable reference (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+
+ 6.2.3.1 GetValue (V)
+
+ 1. ReturnIfAbrupt(V).
+ 2. If Type(V) is not Reference, return V.
+ 3. Let base be GetBase(V).
+ 4. If IsUnresolvableReference(V), throw a ReferenceError exception.
+---*/
+
+assert.throws(ReferenceError, function() {
+ for (let { x = unresolvableReference } of [{}]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-trailing-comma.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-trailing-comma.js
new file mode 100644
index 0000000000..08c770b922
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-id-trailing-comma.js
@@ -0,0 +1,56 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-trailing-comma.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Trailing comma is allowed following BindingPropertyList (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+
+ ObjectBindingPattern[Yield] :
+ { }
+ { BindingPropertyList[?Yield] }
+ { BindingPropertyList[?Yield] , }
+---*/
+
+var iterCount = 0;
+
+for (let { x, } of [{ x: 23 }]) {
+ assert.sameValue(x, 23);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-init-err.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-init-err.js
new file mode 100644
index 0000000000..88325bbe6a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-init-err.js
@@ -0,0 +1,18 @@
+// |reftest| error:SyntaxError
+// Copyright (C) 2019 Aleksey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-iteration-statements
+description: >
+ Initializer is not allowed in head's ForDeclaration position.
+info: |
+ IterationStatement:
+ for (ForDeclaration of AssignmentExpression) Statement
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for (let {x} = 1 of []) {}
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-list-err.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-list-err.js
new file mode 100644
index 0000000000..4062d8cba0
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-list-err.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-list-err.case
+// - src/dstr-binding/error/for-of-let.template
+/*---
+description: Binding property list evaluation is interrupted by an abrupt completion (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.5 Runtime Semantics: BindingInitialization
+
+ BindingPropertyList : BindingPropertyList , BindingProperty
+
+ 1. Let status be the result of performing BindingInitialization for
+ BindingPropertyList using value and environment as arguments.
+ 2. ReturnIfAbrupt(status).
+---*/
+var initCount = 0;
+function thrower() {
+ throw new Test262Error();
+}
+
+assert.throws(Test262Error, function() {
+ for (let { a, b = thrower(), c = ++initCount } of [{}]) {
+ return;
+ }
+});
+
+assert.sameValue(initCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-ary-init.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-ary-init.js
new file mode 100644
index 0000000000..70e5fb41e4
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-ary-init.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-ary-init.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Object binding pattern with "nested" array binding pattern using initializer (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+ 4. Return the result of performing BindingInitialization for BindingPattern
+ passing v and environment as arguments.
+---*/
+
+var iterCount = 0;
+
+for (let { w: [x, y, z] = [4, 5, 6] } of [{}]) {
+ assert.sameValue(x, 4);
+ assert.sameValue(y, 5);
+ assert.sameValue(z, 6);
+
+ assert.throws(ReferenceError, function() {
+ w;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-ary-trailing-comma.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-ary-trailing-comma.js
new file mode 100644
index 0000000000..2e591bda71
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-ary-trailing-comma.js
@@ -0,0 +1,56 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-ary-trailing-comma.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Trailing comma is allowed following BindingPropertyList (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+
+ ObjectBindingPattern[Yield] :
+ { }
+ { BindingPropertyList[?Yield] }
+ { BindingPropertyList[?Yield] , }
+---*/
+
+var iterCount = 0;
+
+for (let { x: [y], } of [{ x: [45] }]) {
+ assert.sameValue(y,45);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-ary-value-null.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-ary-value-null.js
new file mode 100644
index 0000000000..6598982c47
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-ary-value-null.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-ary-value-null.case
+// - src/dstr-binding/error/for-of-let.template
+/*---
+description: Object binding pattern with "nested" array binding pattern taking the `null` value (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ [...]
+ 4. Return the result of performing BindingInitialization for BindingPattern
+ passing v and environment as arguments.
+---*/
+
+assert.throws(TypeError, function() {
+ for (let { w: [x, y, z] = [4, 5, 6] } of [{ w: null }]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-ary.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-ary.js
new file mode 100644
index 0000000000..d92b0bf095
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-ary.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-ary.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Object binding pattern with "nested" array binding pattern not using initializer (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ [...]
+ 4. Return the result of performing BindingInitialization for BindingPattern
+ passing v and environment as arguments.
+---*/
+
+var iterCount = 0;
+
+for (let { w: [x, y, z] = [4, 5, 6] } of [{ w: [7, undefined, ] }]) {
+ assert.sameValue(x, 7);
+ assert.sameValue(y, undefined);
+ assert.sameValue(z, undefined);
+
+ assert.throws(ReferenceError, function() {
+ w;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-eval-err.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-eval-err.js
new file mode 100644
index 0000000000..d8af00ee04
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-eval-err.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-eval-err.case
+// - src/dstr-binding/error/for-of-let.template
+/*---
+description: Evaluation of property name returns an abrupt completion (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.5 Runtime Semantics: BindingInitialization
+
+ BindingProperty : PropertyName : BindingElement
+
+ 1. Let P be the result of evaluating PropertyName
+ 2. ReturnIfAbrupt(P).
+---*/
+function thrower() {
+ throw new Test262Error();
+}
+
+assert.throws(Test262Error, function() {
+ for (let { [thrower()]: x } of [{}]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id-get-value-err.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id-get-value-err.js
new file mode 100644
index 0000000000..377f712820
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id-get-value-err.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-id-get-value-err.case
+// - src/dstr-binding/error/for-of-let.template
+/*---
+description: Error thrown when accessing the corresponding property of the value object (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ BindingElement : BindingPattern Initializeropt
+
+ 1. Let v be GetV(value, propertyName).
+ 2. ReturnIfAbrupt(v).
+---*/
+var initEvalCount = 0;
+var poisonedProperty = Object.defineProperty({}, 'poisoned', {
+ get: function() {
+ throw new Test262Error();
+ }
+});
+
+assert.throws(Test262Error, function() {
+ for (let { poisoned: x = ++initEvalCount } of [poisonedProperty]) {
+ return;
+ }
+});
+
+assert.sameValue(initEvalCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id-init-skipped.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id-init-skipped.js
new file mode 100644
index 0000000000..3b0aa20fa9
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id-init-skipped.js
@@ -0,0 +1,78 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-id-init-skipped.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Destructuring initializer is not evaluated when value is not `undefined` (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ BindingElement : BindingPattern Initializeropt
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ [...]
+---*/
+var initCount = 0;
+function counter() {
+ initCount += 1;
+}
+
+var iterCount = 0;
+
+for (let { s: t = counter(), u: v = counter(), w: x = counter(), y: z = counter() } of [{ s: null, u: 0, w: false, y: '' }]) {
+ assert.sameValue(t, null);
+ assert.sameValue(v, 0);
+ assert.sameValue(x, false);
+ assert.sameValue(z, '');
+ assert.sameValue(initCount, 0);
+
+ assert.throws(ReferenceError, function() {
+ s;
+ });
+ assert.throws(ReferenceError, function() {
+ u;
+ });
+ assert.throws(ReferenceError, function() {
+ w;
+ });
+ assert.throws(ReferenceError, function() {
+ y;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id-init-throws.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id-init-throws.js
new file mode 100644
index 0000000000..252bc11ebb
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id-init-throws.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-id-init-throws.case
+// - src/dstr-binding/error/for-of-let.template
+/*---
+description: Error thrown when evaluating the initializer (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ BindingElement : BindingPattern Initializeropt
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+---*/
+function thrower() {
+ throw new Test262Error();
+}
+
+assert.throws(Test262Error, function() {
+ for (let { x: y = thrower() } of [{}]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id-init-unresolvable.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id-init-unresolvable.js
new file mode 100644
index 0000000000..beacb6eb2c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id-init-unresolvable.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-id-init-unresolvable.case
+// - src/dstr-binding/error/for-of-let.template
+/*---
+description: Destructuring initializer is an unresolvable reference (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ BindingElement : BindingPattern Initializeropt
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+
+ 6.2.3.1 GetValue (V)
+
+ 1. ReturnIfAbrupt(V).
+ 2. If Type(V) is not Reference, return V.
+ 3. Let base be GetBase(V).
+ 4. If IsUnresolvableReference(V), throw a ReferenceError exception.
+---*/
+
+assert.throws(ReferenceError, function() {
+ for (let { x: y = unresolvableReference } of [{}]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id-init.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id-init.js
new file mode 100644
index 0000000000..362f8a7b4a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id-init.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-id-init.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Binding as specified via property name, identifier, and initializer (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (let { x: y = 33 } of [{ }]) {
+ assert.sameValue(y, 33);
+ assert.throws(ReferenceError, function() {
+ x;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id-trailing-comma.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id-trailing-comma.js
new file mode 100644
index 0000000000..153a9df8a9
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id-trailing-comma.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-id-trailing-comma.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Trailing comma is allowed following BindingPropertyList (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+
+ ObjectBindingPattern[Yield] :
+ { }
+ { BindingPropertyList[?Yield] }
+ { BindingPropertyList[?Yield] , }
+---*/
+
+var iterCount = 0;
+
+for (let { x: y, } of [{ x: 23 }]) {
+ assert.sameValue(y, 23);
+
+ assert.throws(ReferenceError, function() {
+ x;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id.js
new file mode 100644
index 0000000000..6ce9783e5b
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-id.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-id.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Binding as specified via property name and identifier (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (let { x: y } of [{ x: 23 }]) {
+ assert.sameValue(y, 23);
+ assert.throws(ReferenceError, function() {
+ x;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-obj-init.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-obj-init.js
new file mode 100644
index 0000000000..07a09d319a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-obj-init.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-obj-init.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Object binding pattern with "nested" object binding pattern using initializer (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+ 4. Return the result of performing BindingInitialization for BindingPattern
+ passing v and environment as arguments.
+---*/
+
+var iterCount = 0;
+
+for (let { w: { x, y, z } = { x: 4, y: 5, z: 6 } } of [{ w: undefined }]) {
+ assert.sameValue(x, 4);
+ assert.sameValue(y, 5);
+ assert.sameValue(z, 6);
+
+ assert.throws(ReferenceError, function() {
+ w;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-obj-value-null.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-obj-value-null.js
new file mode 100644
index 0000000000..fb956c7135
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-obj-value-null.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-obj-value-null.case
+// - src/dstr-binding/error/for-of-let.template
+/*---
+description: Object binding pattern with "nested" object binding pattern taking the `null` value (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ [...]
+ 4. Return the result of performing BindingInitialization for BindingPattern
+ passing v and environment as arguments.
+---*/
+
+assert.throws(TypeError, function() {
+ for (let { w: { x, y, z } = { x: 4, y: 5, z: 6 } } of [{ w: null }]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-obj-value-undef.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-obj-value-undef.js
new file mode 100644
index 0000000000..51dbb5df4e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-obj-value-undef.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-obj-value-undef.case
+// - src/dstr-binding/error/for-of-let.template
+/*---
+description: Object binding pattern with "nested" object binding pattern taking the `null` value (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ [...]
+ 4. Return the result of performing BindingInitialization for BindingPattern
+ passing v and environment as arguments.
+---*/
+
+assert.throws(TypeError, function() {
+ for (let { w: { x, y, z } = undefined } of [{ }]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-obj.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-obj.js
new file mode 100644
index 0000000000..ab47647d69
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-prop-obj.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-obj.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Object binding pattern with "nested" object binding pattern not using initializer (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ [...]
+ 4. Return the result of performing BindingInitialization for BindingPattern
+ passing v and environment as arguments.
+---*/
+
+var iterCount = 0;
+
+for (let { w: { x, y, z } = { x: 4, y: 5, z: 6 } } of [{ w: { x: undefined, z: 7 } }]) {
+ assert.sameValue(x, undefined);
+ assert.sameValue(y, undefined);
+ assert.sameValue(z, 7);
+
+ assert.throws(ReferenceError, function() {
+ w;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-rest-getter.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-rest-getter.js
new file mode 100644
index 0000000000..405a223d0f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-rest-getter.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-rest-getter.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Getter is called when obj is being deconstructed to a rest Object (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+---*/
+var count = 0;
+
+var iterCount = 0;
+
+for (let {...x} of [{ get v() { count++; return 2; } }]) {
+ assert.sameValue(count, 1);
+
+ verifyProperty(x, "v", {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: 2
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-rest-skip-non-enumerable.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-rest-skip-non-enumerable.js
new file mode 100644
index 0000000000..2b87b2cbef
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-rest-skip-non-enumerable.js
@@ -0,0 +1,66 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-rest-skip-non-enumerable.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Rest object doesn't contain non-enumerable properties (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+---*/
+var o = {a: 3, b: 4};
+Object.defineProperty(o, "x", { value: 4, enumerable: false });
+
+var iterCount = 0;
+
+for (let {...rest} of [o]) {
+ assert.sameValue(rest.x, undefined);
+
+ verifyProperty(rest, "a", {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: 3
+ });
+
+ verifyProperty(rest, "b", {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: 4
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-rest-val-obj.js b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-rest-val-obj.js
new file mode 100644
index 0000000000..c9f408b6f4
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/let-obj-ptrn-rest-val-obj.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-rest-val-obj.case
+// - src/dstr-binding/default/for-of-let.template
+/*---
+description: Rest object contains just unextracted data (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ [...]
+ iii. Else,
+ 1. Assert: lhsKind is lexicalBinding.
+ 2. Assert: lhs is a ForDeclaration.
+ 3. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and iterationEnv as arguments.
+ [...]
+---*/
+
+var iterCount = 0;
+
+for (let {a, b, ...rest} of [{x: 1, y: 2, a: 5, b: 3}]) {
+ assert.sameValue(rest.a, undefined);
+ assert.sameValue(rest.b, undefined);
+
+ verifyProperty(rest, "x", {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: 1
+ });
+
+ verifyProperty(rest, "y", {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: 2
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-empty-bool.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-empty-bool.js
new file mode 100644
index 0000000000..cb9927622f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-empty-bool.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-empty-bool.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: An ObjectAssignmentPattern without an AssignmentPropertyList requires an object-coercible value (boolean value) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+
+var counter = 0;
+
+for ({} of [false]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-empty-null.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-empty-null.js
new file mode 100644
index 0000000000..361d985be5
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-empty-null.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-empty-null.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: An ObjectAssignmentPattern without an AssignmentPropertyList requires an object-coercible value (null value) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ({} of [null]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-empty-num.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-empty-num.js
new file mode 100644
index 0000000000..4545eb9388
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-empty-num.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-empty-num.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: An ObjectAssignmentPattern without an AssignmentPropertyList requires an object-coercible value (number value) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+
+var counter = 0;
+
+for ({} of [0]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-empty-obj.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-empty-obj.js
new file mode 100644
index 0000000000..f6276f0852
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-empty-obj.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-empty-obj.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: An ObjectAssignmentPattern without an AssignmentPropertyList requires an object-coercible value (object value) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+
+var counter = 0;
+
+for ({} of [{}]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-empty-string.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-empty-string.js
new file mode 100644
index 0000000000..14d2b37c1d
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-empty-string.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-empty-string.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: An ObjectAssignmentPattern without an AssignmentPropertyList requires an object-coercible value (string value) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+
+var counter = 0;
+
+for ({} of ['']) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-empty-symbol.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-empty-symbol.js
new file mode 100644
index 0000000000..61755aba3f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-empty-symbol.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-empty-symbol.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: An ObjectAssignmentPattern without an AssignmentPropertyList requires an object-coercible value (symbol value) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var s = Symbol();
+
+var counter = 0;
+
+for ({} of [s]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-empty-undef.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-empty-undef.js
new file mode 100644
index 0000000000..890974faf5
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-empty-undef.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-empty-undef.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: An ObjectAssignmentPattern without an AssignmentPropertyList requires an object-coercible value (undefined value) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ({} of [undefined]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-resolution-first.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-resolution-first.js
new file mode 100644
index 0000000000..70f808185e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-resolution-first.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-identifier-resolution-first.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Evaluation of DestructuringAssignmentTarget (first of many) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x = null;
+var y;
+
+var counter = 0;
+
+for ({ x, y } of [{ x: 3 }]) {
+ assert.sameValue(x, 3);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-resolution-last.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-resolution-last.js
new file mode 100644
index 0000000000..085041b37d
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-resolution-last.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-identifier-resolution-last.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Evaluation of DestructuringAssignmentTarget (last of many) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x = null;
+var w;
+
+var counter = 0;
+
+for ({ w, x } of [{ x: 4 }]) {
+ assert.sameValue(x, 4);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-resolution-lone.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-resolution-lone.js
new file mode 100644
index 0000000000..61fc0d65fa
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-resolution-lone.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-identifier-resolution-lone.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Evaluation of DestructuringAssignmentTarget (lone identifier) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x = null;
+
+var counter = 0;
+
+for ({ x, } of [{ x: 2 }]) {
+ assert.sameValue(x, 2);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-resolution-middle.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-resolution-middle.js
new file mode 100644
index 0000000000..febd089b8b
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-resolution-middle.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-identifier-resolution-middle.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Evaluation of DestructuringAssignmentTarget (within many) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x = null;
+var w, y;
+
+var counter = 0;
+
+for ({ w, x, y } of [{ x: 5 }]) {
+ assert.sameValue(x, 5);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-resolution-trlng.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-resolution-trlng.js
new file mode 100644
index 0000000000..02e6c6779f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-resolution-trlng.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-identifier-resolution-trlng.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Evaluation of DestructuringAssignmentTarget (lone identifier with trailing comma) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x = null;
+
+var counter = 0;
+
+for ({ x } of [{ x: 1 }]) {
+ assert.sameValue(x, 1);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-yield-expr.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-yield-expr.js
new file mode 100644
index 0000000000..84ed8fd2c3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.template
+/*---
+description: yield is not a valid IdentifierReference in an AssignmentProperty within generator function bodies. (For..of 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 } of [{}]) ;
+
+});
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-yield-ident-invalid-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-yield-ident-invalid-strict.js
new file mode 100644
index 0000000000..c67a9cc2d6
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.template
+/*---
+description: yield is not a valid IdentifierReference in an AssignmentProperty within strict mode code. (For..of 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 } of [{}]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-yield-ident-valid.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-yield-ident-valid.js
new file mode 100644
index 0000000000..6cc660d6b4
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-identifier-yield-ident-valid.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-identifier-yield-ident-valid.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: yield is a valid IdentifierReference in an AssignmentProperty outside of strict mode and generator functions. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, noStrict]
+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.
+ [...]
+---*/
+var yield;
+
+var counter = 0;
+
+for ({ yield } of [{ yield: 3 }]) {
+ assert.sameValue(yield, 3);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-assignment-missing.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-assignment-missing.js
new file mode 100644
index 0000000000..d284a52c94
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-assignment-missing.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-init-assignment-missing.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: If the Initializer is present and v is undefined, the Initializer should be evaluated and the result assigned to the target reference (no corresponding property defined). (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+for ({ x = 1 } of [{}]) {
+ assert.sameValue(x, 1);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-assignment-null.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-assignment-null.js
new file mode 100644
index 0000000000..176c1aef23
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-assignment-null.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-init-assignment-null.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: If the Initializer is present and v is undefined, the Initializer should be evaluated and the result assigned to the target reference (null property value defined). (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+for ({ x = 1 } of [{ x: null }]) {
+ assert.sameValue(x, null);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-assignment-truthy.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-assignment-truthy.js
new file mode 100644
index 0000000000..68a032b78c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-assignment-truthy.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-init-assignment-truthy.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: If the Initializer is present and v is undefined, the Initializer should be evaluated and the result assigned to the target reference (truthy property value defined). (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+for ({ x = 1 } of [{ x: 2 }]) {
+ assert.sameValue(x, 2);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-assignment-undef.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-assignment-undef.js
new file mode 100644
index 0000000000..8e139d9f14
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-assignment-undef.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-init-assignment-undef.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: If the Initializer is present and v is undefined, the Initializer should be evaluated and the result assigned to the target reference ("undefined" property value defined). (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+for ({ x = 1 } of [{ x: undefined }]) {
+ assert.sameValue(x, 1);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-evaluation.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-evaluation.js
new file mode 100644
index 0000000000..765faed324
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-evaluation.js
@@ -0,0 +1,41 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-init-evaluation.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: The Initializer should only be evaluated if v is undefined. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var flag1 = false;
+var flag2 = false;
+var x, y;
+
+var counter = 0;
+
+for ({ x = flag1 = true, y = flag2 = true } of [{ y: 1 }]) {
+ assert.sameValue(flag1, true);
+ assert.sameValue(flag2, false);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-fn-name-arrow.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-fn-name-arrow.js
new file mode 100644
index 0000000000..f6a3c37add
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-fn-name-arrow.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-init-fn-name-arrow.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Assignment of function `name` attribute (ArrowFunction) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+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.
+ [...]
+
+ AssignmentProperty : IdentifierReference Initializeropt
+ [...] 6. If Initializeropt is present and v is undefined, then
+ [...]
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ i. Let hasNameProperty be HasOwnProperty(v, "name").
+ ii. ReturnIfAbrupt(hasNameProperty).
+ iii. If hasNameProperty is false, perform SetFunctionName(v, P).
+
+---*/
+var arrow;
+
+var counter = 0;
+
+for ({ arrow = () => {} } of [{}]) {
+ verifyProperty(arrow, 'name', {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 'arrow'
+ });
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-fn-name-class.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-fn-name-class.js
new file mode 100644
index 0000000000..e9b35c5bb0
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-fn-name-class.js
@@ -0,0 +1,56 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-init-fn-name-class.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Assignment of function `name` attribute (ClassExpression) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [class, destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+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.
+ [...]
+
+ AssignmentProperty : IdentifierReference Initializeropt
+ [...] 6. If Initializeropt is present and v is undefined, then
+ [...]
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ i. Let hasNameProperty be HasOwnProperty(v, "name").
+ ii. ReturnIfAbrupt(hasNameProperty).
+ iii. If hasNameProperty is false, perform SetFunctionName(v, P).
+
+---*/
+var xCls, cls, xCls2;
+
+var counter = 0;
+
+for ({ xCls = class x {}, cls = class {}, xCls2 = class { static name() {} } } of [{}]) {
+ assert.notSameValue(xCls.name, 'xCls');
+ assert.notSameValue(xCls2.name, 'xCls2');
+
+ verifyProperty(cls, 'name', {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 'cls'
+ });
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-fn-name-cover.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-fn-name-cover.js
new file mode 100644
index 0000000000..d79cbdf0f7
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-fn-name-cover.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-init-fn-name-cover.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Assignment of function `name` attribute (CoverParenthesizedExpression) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+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.
+ [...]
+
+ AssignmentProperty : IdentifierReference Initializeropt
+ [...] 6. If Initializeropt is present and v is undefined, then
+ [...]
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ i. Let hasNameProperty be HasOwnProperty(v, "name").
+ ii. ReturnIfAbrupt(hasNameProperty).
+ iii. If hasNameProperty is false, perform SetFunctionName(v, P).
+
+---*/
+var xCover, cover;
+
+var counter = 0;
+
+for ({ xCover = (0, function() {}), cover = (function() {}) } of [{}]) {
+ assert.notSameValue(xCover.name, 'xCover');
+
+ verifyProperty(cover, 'name', {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 'cover'
+ });
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-fn-name-fn.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-fn-name-fn.js
new file mode 100644
index 0000000000..a9eccefe4d
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-fn-name-fn.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-init-fn-name-fn.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Assignment of function `name` attribute (FunctionExpression) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+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.
+ [...]
+
+ AssignmentProperty : IdentifierReference Initializeropt
+ [...] 6. If Initializeropt is present and v is undefined, then
+ [...]
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ i. Let hasNameProperty be HasOwnProperty(v, "name").
+ ii. ReturnIfAbrupt(hasNameProperty).
+ iii. If hasNameProperty is false, perform SetFunctionName(v, P).
+
+---*/
+var xFn, fn;
+
+var counter = 0;
+
+for ({ xFn = function x() {}, fn = function() {} } of [{}]) {
+ assert.notSameValue(xFn.name, 'xFn');
+
+ verifyProperty(fn, 'name', {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 'fn'
+ });
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-fn-name-gen.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-fn-name-gen.js
new file mode 100644
index 0000000000..e8be796941
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-fn-name-gen.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-init-fn-name-gen.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Assignment of function `name` attribute (GeneratorExpression) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+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.
+ [...]
+
+ AssignmentProperty : IdentifierReference Initializeropt
+ [...] 6. If Initializeropt is present and v is undefined, then
+ [...]
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ i. Let hasNameProperty be HasOwnProperty(v, "name").
+ ii. ReturnIfAbrupt(hasNameProperty).
+ iii. If hasNameProperty is false, perform SetFunctionName(v, P).
+
+---*/
+var xGen, gen;
+
+var counter = 0;
+
+for ({ xGen = function* x() {}, gen = function*() {} } of [{}]) {
+ assert.notSameValue(xGen.name, 'xGen');
+
+ verifyProperty(gen, 'name', {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 'gen'
+ });
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-in.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-in.js
new file mode 100644
index 0000000000..7ffb5e146e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-in.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-init-in.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: The Initializer in an AssignmentProperty may be an `in` expression. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var prop;
+
+var counter = 0;
+
+for ({ prop = 'x' in {} } of [{}]) {
+ assert.sameValue(prop, false);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-let.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-let.js
new file mode 100644
index 0000000000..d520041444
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-let.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-init-let.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: Value retrieval of Initializer obeys `let` semantics. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [let, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+assert.throws(ReferenceError, function() {
+ for ({ x = y } of [{}]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+let y;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-order.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-order.js
new file mode 100644
index 0000000000..cd1a3da4c0
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-order.js
@@ -0,0 +1,41 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-init-order.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Initializer values should be assigned in left-to-right order. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x = 0;
+var a, b;
+
+var counter = 0;
+
+for ({ a = x += 1, b = x *= 2 } of [{}]) {
+ assert.sameValue(a, 1);
+ assert.sameValue(b, 2);
+ assert.sameValue(x, 2);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-simple-no-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-simple-no-strict.js
new file mode 100644
index 0000000000..fe5ba9b801
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-simple-no-strict.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-init-simple-no-strict.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Evaluation of DestructuringAssignmentTarget. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, noStrict]
+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.
+ [...]
+---*/
+var eval, arguments;
+
+var counter = 0;
+
+for ({ eval = 3, arguments = 4 } of [{}]) {
+ assert.sameValue(eval, 3);
+ assert.sameValue(arguments, 4);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-simple-strict-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-simple-strict-strict.js
new file mode 100644
index 0000000000..91a89fe260
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.template
+/*---
+description: It is a Syntax Error if IsValidSimpleAssignmentTarget of IdentifierReference is false. (For..of 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 } of [{}]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-yield-expr.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-yield-expr.js
new file mode 100644
index 0000000000..109aac43d4
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-yield-expr.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-init-yield-expr.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When a `yield` token appears within the Initializer of an AssignmentProperty and within a generator function body, it should behave as a YieldExpression. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var iterationResult, x, iter;
+
+iter = (function*() {
+
+var counter = 0;
+
+for ({ x = yield } of [{}]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+}());
+
+iterationResult = iter.next();
+
+assert.sameValue(iterationResult.value, undefined);
+assert.sameValue(iterationResult.done, false);
+assert.sameValue(x, undefined);
+
+iterationResult = iter.next(3);
+
+assert.sameValue(iterationResult.value, undefined);
+assert.sameValue(iterationResult.done, true);
+assert.sameValue(x, 3);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-yield-ident-invalid-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-yield-ident-invalid-strict.js
new file mode 100644
index 0000000000..b6d735805f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.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..of 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 } of [{}]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-yield-ident-valid.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-yield-ident-valid.js
new file mode 100644
index 0000000000..86e4ac341c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-init-yield-ident-valid.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-init-yield-ident-valid.case
+// - src/dstr-assignment/default/for-of.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..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, noStrict]
+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.
+ [...]
+---*/
+var yield = 3;
+var x;
+
+var counter = 0;
+
+for ({ x = yield } of [{}]) {
+ assert.sameValue(x, 3);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-put-const.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-put-const.js
new file mode 100644
index 0000000000..da31cbd7e1
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-put-const.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-put-const.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: The assignment target should obey `const` semantics. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [const, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+const c = null;
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ({ c } of [{ c: 1 }]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-put-let.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-put-let.js
new file mode 100644
index 0000000000..f5aad869cf
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-put-let.js
@@ -0,0 +1,41 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-put-let.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: The assignment target should obey `let` semantics. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [let, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+
+var counter = 0;
+
+assert.throws(ReferenceError, function() {
+ for ({ x } of [{}]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+let x;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-put-unresolvable-no-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-put-unresolvable-no-strict.js
new file mode 100644
index 0000000000..e7e0f4f855
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-put-unresolvable-no-strict.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-put-unresolvable-no-strict.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Outside of strict mode, if the the assignment target is an unresolvable reference, a new `var` binding should be created in the environment record. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, noStrict]
+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.
+ [...]
+---*/
+{
+
+var counter = 0;
+
+for ({ unresolvable } of [{}]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+}
+
+assert.sameValue(unresolvable, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-put-unresolvable-strict-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-put-unresolvable-strict-strict.js
new file mode 100644
index 0000000000..3a29252147
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-put-unresolvable-strict-strict.js
@@ -0,0 +1,40 @@
+'use strict';
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-put-unresolvable-strict.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: In strict mode, if the the assignment target is an unresolvable reference, a ReferenceError should be thrown. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, onlyStrict]
+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.
+ [...]
+---*/
+
+var counter = 0;
+
+assert.throws(ReferenceError, function() {
+ for ({ unresolvable } of [{}]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-simple-no-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-simple-no-strict.js
new file mode 100644
index 0000000000..3f70f5f919
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-simple-no-strict.js
@@ -0,0 +1,41 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-simple-no-strict.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Evaluation of DestructuringAssignmentTarget. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, noStrict]
+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.
+ [...]
+---*/
+var eval, arguments;
+
+var counter = 0;
+
+for ({ eval, arguments } of [{ eval: 1, arguments: 2 }]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+assert.sameValue(eval, 1);
+assert.sameValue(arguments, 2);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-id-simple-strict-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-id-simple-strict-strict.js
new file mode 100644
index 0000000000..7b10af83c5
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.template
+/*---
+description: It is a Syntax Error if IsValidSimpleAssignmentTarget of IdentifierReference is false. (For..of 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 } of [{}]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-assignment-missing.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-assignment-missing.js
new file mode 100644
index 0000000000..2b3e8553d2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-assignment-missing.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-elem-init-assignment-missing.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: If the Initializer is present and v is undefined, the Initializer should be evaluated and the result assigned to the target reference (non-existent property) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+for ({ y: x = 1 } of [{}]) {
+ assert.sameValue(x, 1);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-assignment-null.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-assignment-null.js
new file mode 100644
index 0000000000..0bffa7dd8c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-assignment-null.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-elem-init-assignment-null.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: If the Initializer is present and v is not undefined, the Initializer should be evaluated and the result assigned to the target reference (null value) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+for ({ y: x = 1 } of [{ y: null }]) {
+ assert.sameValue(x, null);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-assignment-truthy.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-assignment-truthy.js
new file mode 100644
index 0000000000..e09ab3a74a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-assignment-truthy.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-elem-init-assignment-truthy.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: If the Initializer is present and v is not undefined, the Initializer should be evaluated and the result assigned to the target reference (truthy value) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+for ({ y: x = 1 } of [{ y: 2 }]) {
+ assert.sameValue(x, 2);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-assignment-undef.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-assignment-undef.js
new file mode 100644
index 0000000000..a941f7a87a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-assignment-undef.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-elem-init-assignment-undef.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: If the Initializer is present and v is undefined, the Initializer should be evaluated and the result assigned to the target reference (undefined value) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+for ({ y: x = 1 } of [{ y: undefined }]) {
+ assert.sameValue(x, 1);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-evaluation.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-evaluation.js
new file mode 100644
index 0000000000..64720d42c3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-evaluation.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-elem-init-evaluation.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: The Initializer should only be evaluated if v is undefined. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var flag1 = false;
+var flag2 = false;
+var x, y;
+
+var counter = 0;
+
+for ({ x: x = flag1 = true, y: y = flag2 = true } of [{ y: 1 }]) {
+ assert.sameValue(x, true, 'value of `x`');
+ assert.sameValue(flag1, true, 'value of `flag1`');
+ assert.sameValue(y, 1, 'value of `y`');
+ assert.sameValue(flag2, false, 'value of `flag2`');
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-fn-name-arrow.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-fn-name-arrow.js
new file mode 100644
index 0000000000..37d3bd6c71
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-fn-name-arrow.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-elem-init-fn-name-arrow.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Assignment of function `name` attribute (ArrowFunction) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+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.
+ [...]
+
+ AssignmentElement[Yield] : DestructuringAssignmentTarget Initializeropt
+ [...] 7. If Initializer is present and v is undefined and
+ IsAnonymousFunctionDefinition(Initializer) and IsIdentifierRef of
+ DestructuringAssignmentTarget are both true, then
+ a. Let hasNameProperty be HasOwnProperty(rhsValue, "name").
+ b. ReturnIfAbrupt(hasNameProperty).
+ c. If hasNameProperty is false, perform SetFunctionName(rhsValue,
+ GetReferencedName(lref)).
+
+---*/
+var arrow;
+
+var counter = 0;
+
+for ({ x: arrow = () => {} } of [{}]) {
+ verifyProperty(arrow, 'name', {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 'arrow'
+ });
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-fn-name-class.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-fn-name-class.js
new file mode 100644
index 0000000000..a0c138ce84
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-fn-name-class.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-elem-init-fn-name-class.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Assignment of function `name` attribute (ClassExpression) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [class, destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+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.
+ [...]
+
+ AssignmentElement[Yield] : DestructuringAssignmentTarget Initializeropt
+ [...] 7. If Initializer is present and v is undefined and
+ IsAnonymousFunctionDefinition(Initializer) and IsIdentifierRef of
+ DestructuringAssignmentTarget are both true, then
+ a. Let hasNameProperty be HasOwnProperty(rhsValue, "name").
+ b. ReturnIfAbrupt(hasNameProperty).
+ c. If hasNameProperty is false, perform SetFunctionName(rhsValue,
+ GetReferencedName(lref)).
+
+---*/
+var xCls, cls, xCls2;
+
+var counter = 0;
+
+for ({ x: xCls = class x {}, x: cls = class {}, x: xCls2 = class { static name() {} } } of [{}]) {
+ assert.notSameValue(xCls.name, 'xCls');
+ assert.notSameValue(xCls2.name, 'xCls2');
+
+ verifyProperty(cls, 'name', {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 'cls'
+ });
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-fn-name-cover.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-fn-name-cover.js
new file mode 100644
index 0000000000..a2195daf85
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-fn-name-cover.js
@@ -0,0 +1,56 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-elem-init-fn-name-cover.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Assignment of function `name` attribute (CoverParenthesizedExpression) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+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.
+ [...]
+
+ AssignmentElement[Yield] : DestructuringAssignmentTarget Initializeropt
+ [...] 7. If Initializer is present and v is undefined and
+ IsAnonymousFunctionDefinition(Initializer) and IsIdentifierRef of
+ DestructuringAssignmentTarget are both true, then
+ a. Let hasNameProperty be HasOwnProperty(rhsValue, "name").
+ b. ReturnIfAbrupt(hasNameProperty).
+ c. If hasNameProperty is false, perform SetFunctionName(rhsValue,
+ GetReferencedName(lref)).
+
+---*/
+var xCover, cover;
+
+var counter = 0;
+
+for ({ x: xCover = (0, function() {}), x: cover = (function() {}) } of [{}]) {
+ assert.notSameValue(xCover.name, 'xCover');
+
+ verifyProperty(cover, 'name', {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 'cover'
+ });
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-fn-name-fn.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-fn-name-fn.js
new file mode 100644
index 0000000000..6b4e905ab4
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-fn-name-fn.js
@@ -0,0 +1,56 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-elem-init-fn-name-fn.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Assignment of function `name` attribute (FunctionExpression) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+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.
+ [...]
+
+ AssignmentElement[Yield] : DestructuringAssignmentTarget Initializeropt
+ [...] 7. If Initializer is present and v is undefined and
+ IsAnonymousFunctionDefinition(Initializer) and IsIdentifierRef of
+ DestructuringAssignmentTarget are both true, then
+ a. Let hasNameProperty be HasOwnProperty(rhsValue, "name").
+ b. ReturnIfAbrupt(hasNameProperty).
+ c. If hasNameProperty is false, perform SetFunctionName(rhsValue,
+ GetReferencedName(lref)).
+
+---*/
+var xFn, fn;
+
+var counter = 0;
+
+for ({ x: xFn = function x() {}, x: fn = function() {} } of [{}]) {
+ assert.notSameValue(xFn.name, 'xFn');
+
+ verifyProperty(fn, 'name', {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 'fn'
+ });
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-fn-name-gen.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-fn-name-gen.js
new file mode 100644
index 0000000000..a96e87f2d3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-fn-name-gen.js
@@ -0,0 +1,56 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-elem-init-fn-name-gen.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Assignment of function `name` attribute (GeneratorExpression) (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+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.
+ [...]
+
+ AssignmentElement[Yield] : DestructuringAssignmentTarget Initializeropt
+ [...] 7. If Initializer is present and v is undefined and
+ IsAnonymousFunctionDefinition(Initializer) and IsIdentifierRef of
+ DestructuringAssignmentTarget are both true, then
+ a. Let hasNameProperty be HasOwnProperty(rhsValue, "name").
+ b. ReturnIfAbrupt(hasNameProperty).
+ c. If hasNameProperty is false, perform SetFunctionName(rhsValue,
+ GetReferencedName(lref)).
+
+---*/
+var xGen, gen;
+
+var counter = 0;
+
+for ({ x: xGen = function* x() {}, x: gen = function*() {} } of [{}]) {
+ assert.notSameValue(xGen.name, 'xGen');
+
+ verifyProperty(gen, 'name', {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 'gen'
+ });
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-in.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-in.js
new file mode 100644
index 0000000000..ded1a2742b
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-in.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-elem-init-in.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: The Initializer in an AssignmentElement may be an `in` expression. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var prop;
+
+var counter = 0;
+
+for ({ x: prop = 'x' in {} } of [{}]) {
+ assert.sameValue(prop, false);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-let.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-let.js
new file mode 100644
index 0000000000..61d75dfe7e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-let.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-elem-init-let.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: Value retrieval of Initializer obeys `let` semantics. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [let, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+assert.throws(ReferenceError, function() {
+ for ({ x: x = y } of [{}]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+let y;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-yield-expr.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-yield-expr.js
new file mode 100644
index 0000000000..e61d64d533
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-yield-expr.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-elem-init-yield-expr.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When a `yield` token appears within the Initializer of an AssignmentElement and within a generator function body, it should behave as a YieldExpression. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var iterationResult, iter, x;
+iter = (function*() {
+
+var counter = 0;
+
+for ({ x: x = yield } of [{}]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+}());
+
+iterationResult = iter.next();
+
+assert.sameValue(iterationResult.value, undefined);
+assert.sameValue(iterationResult.done, false);
+assert.sameValue(x, undefined);
+
+iterationResult = iter.next(86);
+
+assert.sameValue(iterationResult.value, undefined);
+assert.sameValue(iterationResult.done, true);
+assert.sameValue(x, 86);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-yield-ident-invalid-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-yield-ident-invalid-strict.js
new file mode 100644
index 0000000000..a0488ae63a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.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..of 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 } of [{}]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-yield-ident-valid.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-yield-ident-valid.js
new file mode 100644
index 0000000000..460952544f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-init-yield-ident-valid.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-elem-init-yield-ident-valid.case
+// - src/dstr-assignment/default/for-of.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..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, noStrict]
+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.
+ [...]
+---*/
+var yield = 4;
+var x;
+
+var counter = 0;
+
+for ({ x: x = yield } of [{}]) {
+ assert.sameValue(x, 4);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-memberexpr-optchain-prop-ref-init.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-memberexpr-optchain-prop-ref-init.js
new file mode 100644
index 0000000000..92718cc184
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.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..of 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 } of [{ x: 23 }]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-obj-literal-optchain-prop-ref-init.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-obj-literal-optchain-prop-ref-init.js
new file mode 100644
index 0000000000..630f73e9b0
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.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..of 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} of [{x: 42}]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-obj-literal-prop-ref-init-active.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-obj-literal-prop-ref-init-active.js
new file mode 100644
index 0000000000..69913adcac
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-obj-literal-prop-ref-init-active.js
@@ -0,0 +1,87 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-elem-target-obj-literal-prop-ref-init-active.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: The DestructuringAssignmentTarget of an AssignmentElement can extend to LHSExpressions if it is neither an ObjectLiteral nor an ArrayLiteral and its AssignmentTargetTyp is simple. Using MemberExpression (ObjLiteral + identifier) with active initializer. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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
+
+ AssignmentPattern : ObjectAssignmentPattern
+ ObjectAssignmentPattern : { AssignmentPropertyList }
+ AssignmentPropertyList : AssignmentProperty
+ AssignmentProperty : PropertyName : AssignmentElement
+ AssignmentElement : DestructuringAssignmentTarget Initializer_opt
+ DestructuringAssignmentTarget : LeftHandSideExpression
+
+ Static Semantics: Early Errors
+
+ DestructuringAssignmentTarget : LeftHandSideExpression
+
+ - It is a Syntax Error if LeftHandSideExpression is either an ObjectLiteral or an ArrayLiteral and if LeftHandSideExpression is not covering an AssignmentPattern.
+ - It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple.
+
+ Runtime Semantics: DestructuringAssignmentEvaluation
+ ObjectAssignmentPattern : { AssignmentPropertyList }
+
+ 1. Perform ? RequireObjectCoercible(value).
+ 2. Perform ? PropertyDestructuringAssignmentEvaluation for AssignmentPropertyList using value as the argument.
+ 3. Return NormalCompletion(empty).
+
+ Runtime Semantics: PropertyDestructuringAssignmentEvaluation
+
+ AssignmentProperty : PropertyName : AssignmentElement
+
+ 1. Let name be the result of evaluating PropertyName.
+ 2. ReturnIfAbrupt(name).
+ 3. Perform ? KeyedDestructuringAssignmentEvaluation of AssignmentElement with value and name as the arguments.
+ 4. Return a new List containing name.
+
+ Runtime Semantics: KeyedDestructuringAssignmentEvaluation
+
+ AssignmentElement : DestructuringAssignmentTarget Initializer
+
+ 1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral, then
+ a. Let lref be the result of evaluating DestructuringAssignmentTarget.
+ ...
+
+---*/
+var setValue;
+
+var counter = 0;
+
+for ({ x: {
+ get y() {
+ throw new Test262Error('The property should not be accessed.');
+ },
+ set y(val) {
+ setValue = val;
+ }
+}.y = 42} of [{x: undefined}]) {
+ assert.sameValue(setValue, 42);
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-obj-literal-prop-ref-init.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-obj-literal-prop-ref-init.js
new file mode 100644
index 0000000000..f1b3e5c56f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-obj-literal-prop-ref-init.js
@@ -0,0 +1,87 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-elem-target-obj-literal-prop-ref-init.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: The DestructuringAssignmentTarget of an AssignmentElement can extend to LHSExpressions if it is neither an ObjectLiteral nor an ArrayLiteral and its AssignmentTargetTyp is simple. Using MemberExpression (ObjLiteral + identifier) with initializer. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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
+
+ AssignmentPattern : ObjectAssignmentPattern
+ ObjectAssignmentPattern : { AssignmentPropertyList }
+ AssignmentPropertyList : AssignmentProperty
+ AssignmentProperty : PropertyName : AssignmentElement
+ AssignmentElement : DestructuringAssignmentTarget Initializer_opt
+ DestructuringAssignmentTarget : LeftHandSideExpression
+
+ Static Semantics: Early Errors
+
+ DestructuringAssignmentTarget : LeftHandSideExpression
+
+ - It is a Syntax Error if LeftHandSideExpression is either an ObjectLiteral or an ArrayLiteral and if LeftHandSideExpression is not covering an AssignmentPattern.
+ - It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple.
+
+ Runtime Semantics: DestructuringAssignmentEvaluation
+ ObjectAssignmentPattern : { AssignmentPropertyList }
+
+ 1. Perform ? RequireObjectCoercible(value).
+ 2. Perform ? PropertyDestructuringAssignmentEvaluation for AssignmentPropertyList using value as the argument.
+ 3. Return NormalCompletion(empty).
+
+ Runtime Semantics: PropertyDestructuringAssignmentEvaluation
+
+ AssignmentProperty : PropertyName : AssignmentElement
+
+ 1. Let name be the result of evaluating PropertyName.
+ 2. ReturnIfAbrupt(name).
+ 3. Perform ? KeyedDestructuringAssignmentEvaluation of AssignmentElement with value and name as the arguments.
+ 4. Return a new List containing name.
+
+ Runtime Semantics: KeyedDestructuringAssignmentEvaluation
+
+ AssignmentElement : DestructuringAssignmentTarget Initializer
+
+ 1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral, then
+ a. Let lref be the result of evaluating DestructuringAssignmentTarget.
+ ...
+
+---*/
+var setValue;
+
+var counter = 0;
+
+for ({ x: {
+ get y() {
+ throw new Test262Error('The property should not be accessed.');
+ },
+ set y(val) {
+ setValue = val;
+ }
+}.y = 42} of [{x: 23}]) {
+ assert.sameValue(setValue, 23);
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-obj-literal-prop-ref.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-obj-literal-prop-ref.js
new file mode 100644
index 0000000000..13851a5ef7
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-obj-literal-prop-ref.js
@@ -0,0 +1,87 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-elem-target-obj-literal-prop-ref.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: The DestructuringAssignmentTarget of an AssignmentElement can extend to LHSExpressions if it is neither an ObjectLiteral nor an ArrayLiteral and its AssignmentTargetTyp is simple. Using MemberExpression (ObjLiteral + identifier). (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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
+
+ AssignmentPattern : ObjectAssignmentPattern
+ ObjectAssignmentPattern : { AssignmentPropertyList }
+ AssignmentPropertyList : AssignmentProperty
+ AssignmentProperty : PropertyName : AssignmentElement
+ AssignmentElement : DestructuringAssignmentTarget Initializer_opt
+ DestructuringAssignmentTarget : LeftHandSideExpression
+
+ Static Semantics: Early Errors
+
+ DestructuringAssignmentTarget : LeftHandSideExpression
+
+ - It is a Syntax Error if LeftHandSideExpression is either an ObjectLiteral or an ArrayLiteral and if LeftHandSideExpression is not covering an AssignmentPattern.
+ - It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple.
+
+ Runtime Semantics: DestructuringAssignmentEvaluation
+ ObjectAssignmentPattern : { AssignmentPropertyList }
+
+ 1. Perform ? RequireObjectCoercible(value).
+ 2. Perform ? PropertyDestructuringAssignmentEvaluation for AssignmentPropertyList using value as the argument.
+ 3. Return NormalCompletion(empty).
+
+ Runtime Semantics: PropertyDestructuringAssignmentEvaluation
+
+ AssignmentProperty : PropertyName : AssignmentElement
+
+ 1. Let name be the result of evaluating PropertyName.
+ 2. ReturnIfAbrupt(name).
+ 3. Perform ? KeyedDestructuringAssignmentEvaluation of AssignmentElement with value and name as the arguments.
+ 4. Return a new List containing name.
+
+ Runtime Semantics: KeyedDestructuringAssignmentEvaluation
+
+ AssignmentElement : DestructuringAssignmentTarget Initializer
+
+ 1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral, then
+ a. Let lref be the result of evaluating DestructuringAssignmentTarget.
+ ...
+
+---*/
+var setValue;
+
+var counter = 0;
+
+for ({ x: {
+ get y() {
+ throw new Test262Error('The property should not be accessed.');
+ },
+ set y(val) {
+ setValue = val;
+ }
+}.y} of [{x: 23}]) {
+ assert.sameValue(setValue, 23);
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-yield-expr.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-yield-expr.js
new file mode 100644
index 0000000000..26f4cfcae5
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-yield-expr.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-elem-target-yield-expr.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When a `yield` token appears within the DestructuringAssignmentTarget of an AssignmentElement and within a generator function body, it should behave as a YieldExpression. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x = {};
+var iterationResult, iter;
+
+iter = (function*() {
+
+var counter = 0;
+
+for ({ x: x[yield] } of [{ x: 23 }]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+}());
+
+iterationResult = iter.next();
+
+assert.sameValue(iterationResult.value, undefined);
+assert.sameValue(iterationResult.done, false);
+assert.sameValue(x.prop, undefined);
+
+iterationResult = iter.next('prop');
+
+assert.sameValue(iterationResult.value, undefined);
+assert.sameValue(iterationResult.done, true);
+assert.sameValue(x.prop, 23);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-yield-ident-invalid-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-yield-ident-invalid-strict.js
new file mode 100644
index 0000000000..62023d02c8
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.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..of 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] } of [{}]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-yield-ident-valid.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-yield-ident-valid.js
new file mode 100644
index 0000000000..8b8c4cf229
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-elem-target-yield-ident-valid.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-elem-target-yield-ident-valid.case
+// - src/dstr-assignment/default/for-of.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..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, noStrict]
+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.
+ [...]
+---*/
+var yield = 'prop';
+var x = {};
+
+var counter = 0;
+
+for ({ x: x[yield] } of [{ x: 23 }]) {
+ assert.sameValue(x.prop, 23);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-identifier-resolution-first.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-identifier-resolution-first.js
new file mode 100644
index 0000000000..4fa0e5c937
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-identifier-resolution-first.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-identifier-resolution-first.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Evaluation of DestructuringAssignmentTarget (first of many). (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x = null;
+var y;
+
+var counter = 0;
+
+for ({ a: x, y } of [{ a: 3 }]) {
+ assert.sameValue(x, 3);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-identifier-resolution-last.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-identifier-resolution-last.js
new file mode 100644
index 0000000000..0b61fd7353
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-identifier-resolution-last.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-identifier-resolution-last.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Evaluation of DestructuringAssignmentTarget (last of many). (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x = null;
+var w;
+
+var counter = 0;
+
+for ({ w, a: x } of [{ a: 4 }]) {
+ assert.sameValue(x, 4);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-identifier-resolution-lone.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-identifier-resolution-lone.js
new file mode 100644
index 0000000000..e1f99e8b72
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-identifier-resolution-lone.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-identifier-resolution-lone.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Evaluation of DestructuringAssignmentTarget (lone element). (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x = null;
+
+var counter = 0;
+
+for ({ a: x } of [{ a: 1 }]) {
+ assert.sameValue(x, 1);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-identifier-resolution-middle.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-identifier-resolution-middle.js
new file mode 100644
index 0000000000..e4a03ade77
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-identifier-resolution-middle.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-identifier-resolution-middle.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Evaluation of DestructuringAssignmentTarget (within many). (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x = null;
+var w, y;
+
+var counter = 0;
+
+for ({ w, a: x, y } of [{ a: 5 }]) {
+ assert.sameValue(x, 5);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-identifier-resolution-trlng.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-identifier-resolution-trlng.js
new file mode 100644
index 0000000000..1033983e67
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-identifier-resolution-trlng.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-identifier-resolution-trlng.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Evaluation of DestructuringAssignmentTarget (lone element with trailing comma). (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x = null;
+
+var counter = 0;
+
+for ({ a: x, } of [{ a: 2 }]) {
+ assert.sameValue(x, 2);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-name-evaluation-error.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-name-evaluation-error.js
new file mode 100644
index 0000000000..ee9a330569
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-name-evaluation-error.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-name-evaluation-error.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: Any error raised as a result of evaluating PropertyName should be forwarded to the runtime. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var a, x;
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ({ [a.b]: x } of [{}]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-name-evaluation.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-name-evaluation.js
new file mode 100644
index 0000000000..1a36dd05bf
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-name-evaluation.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-name-evaluation.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: PropertyName of an AssignmentProperty may be a ComputedPropertyName. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x, y, xy;
+
+var counter = 0;
+
+for ({ ['x' + 'y']: x } of [{ x: 1, xy: 23, y: 2 }]) {
+ assert.sameValue(x, 23);
+ assert.sameValue(y, undefined);
+ assert.sameValue(xy, undefined);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array-invalid.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array-invalid.js
new file mode 100644
index 0000000000..32772b6af9
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.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..of 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)] } of [{ x: [] }]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array-null.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array-null.js
new file mode 100644
index 0000000000..c303c01c77
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array-null.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-nested-array-null.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an array literal and the value is `null`, a TypeError should be thrown. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ({ x: [ x ] } of [{ x: null }]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array-undefined-own.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array-undefined-own.js
new file mode 100644
index 0000000000..e2b7cbcef0
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array-undefined-own.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-nested-array-undefined-own.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an array literal and the value is `undefined`, a TypeError should be thrown. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ({ x: [ x ] } of [{ x: undefined }]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array-undefined.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array-undefined.js
new file mode 100644
index 0000000000..3e1525fabf
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array-undefined.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-nested-array-undefined.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an array literal and the value is not defined, a TypeError should be thrown. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ({ x: [ x ] } of [{}]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array-yield-expr.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array-yield-expr.js
new file mode 100644
index 0000000000..c3f8ce19d8
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array-yield-expr.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-nested-array-yield-expr.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When a `yield` token appears within the Initializer of a nested destructuring assignment and within a generator function body, it should behave as a YieldExpression. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var iterationResult, iter, x;
+
+iter = (function*() {
+
+var counter = 0;
+
+for ({ x: [x = yield] } of [{ x: [] }]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+}());
+
+iterationResult = iter.next();
+
+assert.sameValue(iterationResult.value, undefined);
+assert.sameValue(iterationResult.done, false);
+assert.sameValue(x, undefined);
+
+iterationResult = iter.next(24601);
+
+assert.sameValue(iterationResult.value, undefined);
+assert.sameValue(iterationResult.done, true);
+assert.sameValue(x, 24601);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array-yield-ident-invalid-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array-yield-ident-invalid-strict.js
new file mode 100644
index 0000000000..bfd72bbcde
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.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..of 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] } of [{ x: [] }]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array-yield-ident-valid.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array-yield-ident-valid.js
new file mode 100644
index 0000000000..8649b19af2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array-yield-ident-valid.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-nested-array-yield-ident-valid.case
+// - src/dstr-assignment/default/for-of.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..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, noStrict]
+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.
+ [...]
+---*/
+var yield = 22;
+var x;
+
+var counter = 0;
+
+for ({ x: [x = yield] } of [{ x: [] }]) {
+ assert.sameValue(x, 22);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array.js
new file mode 100644
index 0000000000..854f71e280
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-array.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-nested-array.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an array literal, it should be parsed parsed as a DestructuringAssignmentPattern and evaluated as a destructuring assignment. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var y;
+
+var counter = 0;
+
+for ({ x: [y] } of [{ x: [321] }]) {
+ assert.sameValue(y, 321);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj-invalid.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj-invalid.js
new file mode 100644
index 0000000000..75a901e38c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.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..of 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() {} } } of [{ x: {} }]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj-null.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj-null.js
new file mode 100644
index 0000000000..a22a80241b
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj-null.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-nested-obj-null.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an object literal and the value is `null`, a TypeError should be thrown. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ({ x: { x } } of [{ x: null }]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj-undefined-own.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj-undefined-own.js
new file mode 100644
index 0000000000..252451eda9
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj-undefined-own.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-nested-obj-undefined-own.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an object literal and the value is `undefined`, a TypeError should be thrown. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ({ x: { x } } of [{ x: undefined }]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj-undefined.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj-undefined.js
new file mode 100644
index 0000000000..050c25a20d
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj-undefined.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-nested-obj-undefined.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an object literal and the value is not defined, a TypeError should be thrown. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ({ x: { x } } of [{}]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj-yield-expr.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj-yield-expr.js
new file mode 100644
index 0000000000..ab651a62d9
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj-yield-expr.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-nested-obj-yield-expr.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When a `yield` token appears within the Initializer of a nested destructuring assignment and within a generator function body, it should behave as a YieldExpression. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var iterationResult, iter, x = undefined;
+
+iter = (function*() {
+
+var counter = 0;
+
+for ({ x: { x = yield } } of [{ x: {} }]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+}());
+
+iterationResult = iter.next();
+
+assert.sameValue(iterationResult.value, undefined);
+assert.sameValue(iterationResult.done, false);
+assert.sameValue(x, undefined);
+
+iterationResult = iter.next(4);
+
+assert.sameValue(iterationResult.value, undefined);
+assert.sameValue(iterationResult.done, true);
+assert.sameValue(x, 4);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj-yield-ident-invalid-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj-yield-ident-invalid-strict.js
new file mode 100644
index 0000000000..34d4925441
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.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..of 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 } } of [{ x: {} }]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj-yield-ident-valid.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj-yield-ident-valid.js
new file mode 100644
index 0000000000..2e777bda32
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj-yield-ident-valid.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-nested-obj-yield-ident-valid.case
+// - src/dstr-assignment/default/for-of.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..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, noStrict]
+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.
+ [...]
+---*/
+var yield = 2;
+var result, x;
+
+var counter = 0;
+
+for ({ x: { x = yield } } of [{ x: {} }]) {
+ assert.sameValue(x, 2);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj.js
new file mode 100644
index 0000000000..a0bf42f420
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-nested-obj.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-nested-obj.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an object literal, it should be parsed as a DestructuringAssignmentPattern and evaluated as a destructuring assignment. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var result, y;
+
+var counter = 0;
+
+for ({ x: { y } } of [{ x: { y: 2 } }]) {
+ assert.sameValue(y, 2);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-const.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-const.js
new file mode 100644
index 0000000000..c4df6acda3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-const.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-put-const.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: The assignment target should obey `const` semantics. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [const, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+const c = 1;
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ({ a: c } of [{ a: 2 }]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-let.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-let.js
new file mode 100644
index 0000000000..e60d8ec97a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-let.js
@@ -0,0 +1,41 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-put-let.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: The assignment target should obey `let` semantics. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [let, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+
+var counter = 0;
+
+assert.throws(ReferenceError, function() {
+ for ({ a: x } of [{}]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+let x;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-order.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-order.js
new file mode 100644
index 0000000000..771ced57d8
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-order.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-put-order.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: The AssignmentElements in an AssignmentElementList are evaluated in left- to-right order. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+
+var counter = 0;
+
+for ({ z: x, a: x } of [{ a: 2, z: 1 }]) {
+ assert.sameValue(x, 2);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-prop-ref-no-get.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-prop-ref-no-get.js
new file mode 100644
index 0000000000..e17cb37070
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-prop-ref-no-get.js
@@ -0,0 +1,46 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-put-prop-ref-no-get.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: If the DestructuringAssignmentTarget of an AssignmentElement is a PropertyReference, it should not be evaluated. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var setValue;
+var x = {
+ get y() {
+ throw new Test262Error('The property should not be accessed.');
+ },
+ set y(val) {
+ setValue = val;
+ }
+};
+
+var counter = 0;
+
+for ({ a: x.y } of [{ a: 23 }]) {
+ assert.sameValue(setValue, 23);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-prop-ref-user-err.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-prop-ref-user-err.js
new file mode 100644
index 0000000000..cc2ae08add
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-prop-ref-user-err.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-put-prop-ref-user-err.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: Any error raised as a result of setting the value should be forwarded to the runtime. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x = {
+ set y(val) {
+ throw new Test262Error();
+ }
+};
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ({ a: x.y } of [{ a: 23 }]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-prop-ref.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-prop-ref.js
new file mode 100644
index 0000000000..346f16d0eb
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-prop-ref.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-put-prop-ref.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: The DestructuringAssignmentTarget of an AssignmentElement may be a PropertyReference. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x = {};
+
+var counter = 0;
+
+for ({ xy: x.y } of [{ xy: 4 }]) {
+ assert.sameValue(x.y, 4);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-unresolvable-no-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-unresolvable-no-strict.js
new file mode 100644
index 0000000000..e19b7538f4
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-unresolvable-no-strict.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-put-unresolvable-no-strict.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Outside of strict mode, if the the assignment target is an unresolvable reference, a new `var` binding should be created in the environment record. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, noStrict]
+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.
+ [...]
+---*/
+{
+
+var counter = 0;
+
+for ({ x: unresolvable } of [{}]) {
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+}
+
+assert.sameValue(unresolvable, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-unresolvable-strict-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-unresolvable-strict-strict.js
new file mode 100644
index 0000000000..90991b923c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-prop-put-unresolvable-strict-strict.js
@@ -0,0 +1,40 @@
+'use strict';
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-put-unresolvable-strict.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: In strict mode, if the the assignment target is an unresolvable reference, a ReferenceError should be thrown. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, onlyStrict]
+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.
+ [...]
+---*/
+
+var counter = 0;
+
+assert.throws(ReferenceError, function() {
+ for ({ x: unresolvable } of [{}]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-computed-property-no-strict.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-computed-property-no-strict.js
new file mode 100644
index 0000000000..4aa57feee7
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-computed-property-no-strict.js
@@ -0,0 +1,56 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-rest-computed-property-no-strict.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Destructuring field can be a computed property, i.e it can be defined only at runtime. Rest operantion needs to skip these properties as well. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated, noStrict]
+includes: [propertyHelper.js]
+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.
+ [...]
+---*/
+var a = "foo";
+
+var counter = 0;
+
+for ({[a]:b, ...rest} of [{ foo: 1, bar: 2, baz: 3 }]) {
+ assert.sameValue(b, 1);
+ assert.sameValue(rest.bar, 2);
+ assert.sameValue(rest.baz, 3);
+
+ assert.sameValue(Object.getOwnPropertyDescriptor(rest, "foo"), undefined);
+
+ verifyProperty(rest, "bar", {
+ enumerable: true,
+ writable: true,
+ configurable: true
+ });
+
+ verifyProperty(rest, "baz", {
+ enumerable: true,
+ writable: true,
+ configurable: true
+ });
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-computed-property.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-computed-property.js
new file mode 100644
index 0000000000..91efd46098
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-computed-property.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-rest-computed-property.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Destructuring field can be a computed property, i.e it can be defined only at runtime. Rest operantion needs to skip these properties as well. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+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.
+ [...]
+---*/
+var a = "foo";
+var b, rest;
+
+var counter = 0;
+
+for ({[a]:b, ...rest} of [{ foo: 1, bar: 2, baz: 3 }]) {
+ assert.sameValue(b, 1);
+ assert.sameValue(rest.bar, 2);
+ assert.sameValue(rest.baz, 3);
+
+ assert.sameValue(Object.getOwnPropertyDescriptor(rest, "foo"), undefined);
+
+ verifyProperty(rest, "bar", {
+ enumerable: true,
+ writable: true,
+ configurable: true
+ });
+
+ verifyProperty(rest, "baz", {
+ enumerable: true,
+ writable: true,
+ configurable: true
+ });
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-descriptors.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-descriptors.js
new file mode 100644
index 0000000000..155d66471e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-descriptors.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-rest-descriptors.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Object created from rest deconstruction doesn't copy source object property descriptors. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+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.
+ [...]
+---*/
+var rest;
+var obj = {};
+Object.defineProperty(obj, "a", { value: 3, configurable: false, enumerable: true });
+Object.defineProperty(obj, "b", { value: 4, writable: false, enumerable: true });
+
+var counter = 0;
+
+for ({...rest} of [obj]) {
+ verifyProperty(rest, "a", {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: 3
+ });
+
+ verifyProperty(rest, "b", {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: 4
+ });
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-empty-obj.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-empty-obj.js
new file mode 100644
index 0000000000..9b8df060f6
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-empty-obj.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-rest-empty-obj.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: RestBindingInitialization creates a new object even if lhs is an empty object (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var rest;
+
+
+var counter = 0;
+
+for ({...rest} of [{}]) {
+ assert.notSameValue(rest, undefined);
+ assert.notSameValue(rest, null);
+ assert.sameValue(typeof rest, "object");
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-getter-abrupt-get-error.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-getter-abrupt-get-error.js
new file mode 100644
index 0000000000..2ded1386e6
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-getter-abrupt-get-error.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-rest-getter-abrupt-get-error.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: Rest deconstruction doesn't happen if getter return is abrupt (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var x;
+var count = 0;
+
+var counter = 0;
+
+assert.throws(Test262Error, function() {
+ for ({...x} of [{ get v() { count++; throw new Test262Error(); } }]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+assert.sameValue(count, 1);
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-getter.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-getter.js
new file mode 100644
index 0000000000..cbef6499a3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-getter.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-rest-getter.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Getter is called when obj is being deconstructed to a rest Object (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+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.
+ [...]
+---*/
+var x;
+var count = 0;
+
+var counter = 0;
+
+for ({...x} of [{ get v() { count++; return 2; } }]) {
+ assert.sameValue(count, 1);
+
+ verifyProperty(x, "v", {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: 2
+ });
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-1.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-1.js
new file mode 100644
index 0000000000..e792320e89
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-1.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-rest-non-string-computed-property-1.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Destructuring field can be a non-string computed property, i.e it can be defined only at runtime. Rest operation needs to skip these properties as well. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+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.
+ [...]
+---*/
+var a = 1.;
+var b, rest;
+
+var counter = 0;
+
+for ({[a]:b, ...rest} of [{[a]: 1, bar: 2 }]) {
+ assert.sameValue(b, 1);
+
+ assert.sameValue(Object.getOwnPropertyDescriptor(rest, "1"), undefined);
+
+ verifyProperty(rest, "bar", {
+ value: 2,
+ enumerable: true,
+ writable: true,
+ configurable: true
+ });
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-1dot.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-1dot.js
new file mode 100644
index 0000000000..35c257b14c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-1dot.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-rest-non-string-computed-property-1dot.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Destructuring field can be a non-string computed property, i.e it can be defined only at runtime. Rest operation needs to skip these properties as well. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+includes: [compareArray.js, propertyHelper.js]
+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.
+ [...]
+---*/
+var a = 1.;
+var b, rest;
+
+var counter = 0;
+
+for ({[a]:b, ...rest} of [{[a]: [1], bar: 2 }]) {
+ assert.compareArray(b, [1]);
+
+ assert.sameValue(Object.getOwnPropertyDescriptor(rest, "1"), undefined);
+
+ verifyProperty(rest, "bar", {
+ value: 2,
+ enumerable: true,
+ writable: true,
+ configurable: true
+ });
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-1dot0.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-1dot0.js
new file mode 100644
index 0000000000..7860eb4412
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-1dot0.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-rest-non-string-computed-property-1dot0.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Destructuring field can be a non-string computed property, i.e it can be defined only at runtime. Rest operation needs to skip these properties as well. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+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.
+ [...]
+---*/
+var a = 1.;
+var b, rest;
+
+var counter = 0;
+
+for ({[a]:b, ...rest} of [{[a]: 1.0, bar: 2 }]) {
+ assert.sameValue(b, 1);
+
+ assert.sameValue(Object.getOwnPropertyDescriptor(rest, "1"), undefined);
+
+ verifyProperty(rest, "bar", {
+ value: 2,
+ enumerable: true,
+ writable: true,
+ configurable: true
+ });
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-1e0.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-1e0.js
new file mode 100644
index 0000000000..8417f17694
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-1e0.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-rest-non-string-computed-property-1e0.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Destructuring field can be a non-string computed property, i.e it can be defined only at runtime. Rest operation needs to skip these properties as well. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+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.
+ [...]
+---*/
+var a = 1.;
+var b, rest;
+
+var counter = 0;
+
+for ({[a]:b, ...rest} of [{[a]: 1e0, bar: 2 }]) {
+ assert.sameValue(b, 1);
+
+ assert.sameValue(Object.getOwnPropertyDescriptor(rest, "1"), undefined);
+
+ verifyProperty(rest, "bar", {
+ value: 2,
+ enumerable: true,
+ writable: true,
+ configurable: true
+ });
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-array-1.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-array-1.js
new file mode 100644
index 0000000000..17417644d4
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-array-1.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-rest-non-string-computed-property-array-1.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Destructuring field can be a non-string computed property, i.e it can be defined only at runtime. Rest operation needs to skip these properties as well. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+includes: [compareArray.js, propertyHelper.js]
+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.
+ [...]
+---*/
+var a = 1.;
+var b, rest;
+
+var counter = 0;
+
+for ({[a]:b, ...rest} of [{[a]: [1], bar: 2 }]) {
+ assert.compareArray(b, [1]);
+
+ assert.sameValue(Object.getOwnPropertyDescriptor(rest, "1"), undefined);
+
+ verifyProperty(rest, "bar", {
+ value: 2,
+ enumerable: true,
+ writable: true,
+ configurable: true
+ });
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-array-1e0.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-array-1e0.js
new file mode 100644
index 0000000000..c11cded9aa
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-array-1e0.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-rest-non-string-computed-property-array-1e0.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Destructuring field can be a non-string computed property, i.e it can be defined only at runtime. Rest operation needs to skip these properties as well. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+includes: [compareArray.js, propertyHelper.js]
+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.
+ [...]
+---*/
+var a = 1.;
+var b, rest;
+
+var counter = 0;
+
+for ({[a]:b, ...rest} of [{[a]: [1e0], bar: 2 }]) {
+ assert.compareArray(b, [1]);
+
+
+ assert.sameValue(Object.getOwnPropertyDescriptor(rest, "1"), undefined);
+
+ verifyProperty(rest, "bar", {
+ value: 2,
+ enumerable: true,
+ writable: true,
+ configurable: true
+ });
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-string-1.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-string-1.js
new file mode 100644
index 0000000000..d3929f611f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-non-string-computed-property-string-1.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-rest-non-string-computed-property-string-1.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Destructuring field can be a non-string computed property, i.e it can be defined only at runtime. Rest operation needs to skip these properties as well. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+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.
+ [...]
+---*/
+var a = 1.;
+var b, rest;
+
+var counter = 0;
+
+for ({[a]:b, ...rest} of [{[a]: "1", bar: 2 }]) {
+ assert.sameValue(b, "1");
+
+ assert.sameValue(Object.getOwnPropertyDescriptor(rest, "1"), undefined);
+
+ verifyProperty(rest, "bar", {
+ value: 2,
+ enumerable: true,
+ writable: true,
+ configurable: true
+ });
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-not-last-element-invalid.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-not-last-element-invalid.js
new file mode 100644
index 0000000000..775541cf1a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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-of.template
+/*---
+description: Object rest element needs to be the last AssignmenProperty in ObjectAssignmentPattern. (For..of 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} of [{}
+]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-number.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-number.js
new file mode 100644
index 0000000000..1f007579bd
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-number.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-rest-number.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: RestBindingInitialization creates a new object even if lhs is a Number (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var rest;
+
+
+var counter = 0;
+
+for ({...rest} of [51]) {
+ assert.notSameValue(rest, undefined);
+ assert.notSameValue(rest, null);
+ assert(rest instanceof Object);
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-order.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-order.js
new file mode 100644
index 0000000000..8b6767c502
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-order.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-rest-order.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Rest operation follows [[OwnPropertyKeys]] order (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol, object-rest, destructuring-binding]
+flags: [generated]
+includes: [compareArray.js]
+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.
+ [...]
+---*/
+var rest;
+var calls = [];
+var o = { get z() { calls.push('z') }, get a() { calls.push('a') } };
+Object.defineProperty(o, 1, { get: () => { calls.push(1) }, enumerable: true });
+Object.defineProperty(o, Symbol('foo'), { get: () => { calls.push("Symbol(foo)") }, enumerable: true });
+
+var counter = 0;
+
+for ({...rest} of [o]) {
+ assert.compareArray(calls, [1, 'z', 'a', "Symbol(foo)"]);
+ assert.sameValue(Object.keys(rest).length, 3);
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-put-const.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-put-const.js
new file mode 100644
index 0000000000..0ddcc9aadd
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-put-const.js
@@ -0,0 +1,41 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-rest-put-const.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: The object rest deconstruction assignment target should obey `const` semantics. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+const rest = null;
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ({...rest} of [{}
+]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-same-name.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-same-name.js
new file mode 100644
index 0000000000..a51b2c71ea
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-same-name.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-rest-same-name.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Proper setting in the values for rest name equal to a property name. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var o = {
+ x: 42,
+ y: 39,
+ z: 'cheeseburger'
+};
+
+var x, y, z;
+
+var counter = 0;
+
+for ({ x, ...z } of [o]) {
+ assert.sameValue(x, 42);
+ assert.sameValue(y, undefined);
+ assert.sameValue(z.y, 39);
+ assert.sameValue(z.z, 'cheeseburger');
+
+ var keys = Object.getOwnPropertyNames(z);
+ assert.sameValue(keys.length, 2);
+ assert.sameValue(keys[0], 'y');
+ assert.sameValue(keys[1], 'z');
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-skip-non-enumerable.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-skip-non-enumerable.js
new file mode 100644
index 0000000000..9c0c4e53f2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-skip-non-enumerable.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-rest-skip-non-enumerable.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Rest object doesn't contain non-enumerable properties (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+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.
+ [...]
+---*/
+var rest;
+var obj = {a: 3, b: 4};
+Object.defineProperty(obj, "x", { value: 4, enumerable: false });
+
+var counter = 0;
+
+for ({...rest} of [obj]) {
+ assert.sameValue(Object.getOwnPropertyDescriptor(rest, "x"), undefined);
+
+ verifyProperty(rest, "a", {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: 3
+ });
+
+ verifyProperty(rest, "b", {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: 4
+ });
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-str-val.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-str-val.js
new file mode 100644
index 0000000000..e8593e80c8
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-str-val.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-rest-str-val.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: RestBindingInitialization creats an object with indexes as property name (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var rest;
+
+
+var counter = 0;
+
+for ({...rest} of ["foo"]) {
+ assert.sameValue(rest["0"], "f");
+ assert.sameValue(rest["1"], "o");
+ assert.sameValue(rest["2"], "o");
+ assert(rest instanceof Object);
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-symbol-val.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-symbol-val.js
new file mode 100644
index 0000000000..1602f40ce1
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-symbol-val.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-rest-symbol-val.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: RestBindingInitialization creates a new object if lhs is a Symbol (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol, object-rest, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var rest;
+
+
+var counter = 0;
+
+for ({...rest} of [Symbol("foo")]) {
+ assert.notSameValue(rest, undefined);
+ assert.notSameValue(rest, null);
+ assert(rest instanceof Object);
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-to-property-with-setter.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-to-property-with-setter.js
new file mode 100644
index 0000000000..0ac23409db
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-to-property-with-setter.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-rest-to-property-with-setter.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an object property setter, its value should be binded as rest object. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var settedValue;
+var executedGetter = false;
+var src = {
+ get y() { executedGetter = true; },
+ set y(v) {
+ settedValue = v;
+ }
+}
+src.y = undefined;
+
+var counter = 0;
+
+for ({...src.y} of [{ x: 1, y: 2}]) {
+ assert.sameValue(settedValue.x, 1);
+ assert.sameValue(settedValue.y, 2);
+ assert(!executedGetter, "The property should not be accessed");
+
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-to-property.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-to-property.js
new file mode 100644
index 0000000000..f04383825c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-to-property.js
@@ -0,0 +1,46 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-rest-to-property.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: When DestructuringAssignmentTarget is an object property, its value should be binded as rest object. (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+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.
+ [...]
+---*/
+var src = {};
+
+var counter = 0;
+
+for ({...src.y} of [{ x: 1, y: 2}]) {
+ assert.sameValue(src.y.x, 1);
+ assert.sameValue(src.y.y, 2);
+
+ verifyProperty(src, "y", {
+ enumerable: true,
+ writable: true,
+ configurable: true
+ });
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-val-null.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-val-null.js
new file mode 100644
index 0000000000..a2509f70ec
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-val-null.js
@@ -0,0 +1,41 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-rest-val-null.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: TypeError is thrown when rhs is null because of 7.1.13 ToObject ( argument ) used by CopyDataProperties (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var rest;
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ({...rest} of [null
+]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-val-undefined.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-val-undefined.js
new file mode 100644
index 0000000000..1390ffa8c9
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-val-undefined.js
@@ -0,0 +1,41 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-rest-val-undefined.case
+// - src/dstr-assignment/error/for-of.template
+/*---
+description: TypeError is thrown when rhs is ```undefined``` because of 7.1.13 ToObject ( argument ) used by CopyDataProperties (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+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.
+ [...]
+---*/
+var rest;
+
+var counter = 0;
+
+assert.throws(TypeError, function() {
+ for ({...rest} of [undefined
+]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-valid-object.js b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-valid-object.js
new file mode 100644
index 0000000000..ef2b94d0ca
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/obj-rest-valid-object.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-rest-valid-object.case
+// - src/dstr-assignment/default/for-of.template
+/*---
+description: Rest object contains just unextracted data (For..of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+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.
+ [...]
+---*/
+var rest, a, b;
+
+
+var counter = 0;
+
+for ({a, b, ...rest} of [{x: 1, y: 2, a: 5, b: 3}]) {
+ assert.sameValue(rest.a, undefined);
+ assert.sameValue(rest.b, undefined);
+
+ verifyProperty(rest, "x", {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: 1
+ });
+
+ verifyProperty(rest, "y", {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: 2
+ });
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/shell.js b/js/src/tests/test262/language/statements/for-of/dstr/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/shell.js
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-init-iter-close.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-init-iter-close.js
new file mode 100644
index 0000000000..d3f0dfb328
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-init-iter-close.js
@@ -0,0 +1,69 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-init-iter-close.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Iterator is closed when not exhausted by pattern evaluation (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.5 Runtime Semantics: BindingInitialization
+
+ BindingPattern : ArrayBindingPattern
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, return ? IteratorClose(iterator,
+ result).
+ [...]
+
+---*/
+var doneCallCount = 0;
+var iter = {};
+iter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { value: null, done: false };
+ },
+ return: function() {
+ doneCallCount += 1;
+ return {};
+ }
+ };
+};
+
+var iterCount = 0;
+
+for (var [x] of [iter]) {
+ assert.sameValue(doneCallCount, 1);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-init-iter-get-err-array-prototype.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-init-iter-get-err-array-prototype.js
new file mode 100644
index 0000000000..9677bf06a7
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-init-iter-get-err-array-prototype.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-init-iter-get-err-array-prototype.case
+// - src/dstr-binding/error/for-of-var.template
+/*---
+description: Abrupt completion returned by GetIterator (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ Runtime Semantics: BindingInitialization
+
+ BindingPattern : ArrayBindingPattern
+
+ 1. Let iteratorRecord be ? GetIterator(value).
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ [...]
+ 4. Let iterator be ? Call(method, obj).
+
+ Call ( F, V [ , argumentsList ] )
+
+ [...]
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+
+---*/
+delete Array.prototype[Symbol.iterator];
+
+assert.throws(TypeError, function() {
+ for (var [x, y, z] of [[1, 2, 3]]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-init-iter-get-err.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-init-iter-get-err.js
new file mode 100644
index 0000000000..f0346537ca
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-init-iter-get-err.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-init-iter-get-err.case
+// - src/dstr-binding/error/for-of-var.template
+/*---
+description: Abrupt completion returned by GetIterator (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.5 Runtime Semantics: BindingInitialization
+
+ BindingPattern : ArrayBindingPattern
+
+ 1. Let iterator be GetIterator(value).
+ 2. ReturnIfAbrupt(iterator).
+
+---*/
+var iter = {};
+iter[Symbol.iterator] = function() {
+ throw new Test262Error();
+};
+
+assert.throws(Test262Error, function() {
+ for (var [x] of [iter]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-init-iter-no-close.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-init-iter-no-close.js
new file mode 100644
index 0000000000..94ecd846d3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-init-iter-no-close.js
@@ -0,0 +1,69 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-init-iter-no-close.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Iterator is not closed when exhausted by pattern evaluation (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.5 Runtime Semantics: BindingInitialization
+
+ BindingPattern : ArrayBindingPattern
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, return ? IteratorClose(iterator,
+ result).
+ [...]
+
+---*/
+var doneCallCount = 0;
+var iter = {};
+iter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { value: null, done: true };
+ },
+ return: function() {
+ doneCallCount += 1;
+ return {};
+ }
+ };
+};
+
+var iterCount = 0;
+
+for (var [x] of [iter]) {
+ assert.sameValue(doneCallCount, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-name-iter-val.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-name-iter-val.js
new file mode 100644
index 0000000000..8541f8ba15
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-name-iter-val.js
@@ -0,0 +1,68 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-name-iter-val.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: SingleNameBinding with normal value iteration (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (var [x, y, z] of [[1, 2, 3]]) {
+ assert.sameValue(x, 1);
+ assert.sameValue(y, 2);
+ assert.sameValue(z, 3);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-elem-init.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-elem-init.js
new file mode 100644
index 0000000000..e436b89a97
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-elem-init.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-elem-init.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: BindingElement with array binding pattern and initializer is used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ [...]
+ 2. If iteratorRecord.[[done]] is true, let v be undefined.
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be ? GetValue(defaultValue).
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+
+var iterCount = 0;
+
+for (var [[x, y, z] = [4, 5, 6]] of [[]]) {
+ assert.sameValue(x, 4);
+ assert.sameValue(y, 5);
+ assert.sameValue(z, 6);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-elem-iter.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-elem-iter.js
new file mode 100644
index 0000000000..610d4adb76
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-elem-iter.js
@@ -0,0 +1,61 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-elem-iter.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: BindingElement with array binding pattern and initializer is not used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ 1. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ [...]
+ e. Else,
+ i. Let v be IteratorValue(next).
+ [...]
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+
+var iterCount = 0;
+
+for (var [[x, y, z] = [4, 5, 6]] of [[[7, 8, 9]]]) {
+ assert.sameValue(x, 7);
+ assert.sameValue(y, 8);
+ assert.sameValue(z, 9);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-elision-init.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-elision-init.js
new file mode 100644
index 0000000000..084451edc6
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-elision-init.js
@@ -0,0 +1,67 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-elision-init.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: BindingElement with array binding pattern and initializer is used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ [...]
+ 2. If iteratorRecord.[[done]] is true, let v be undefined.
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be ? GetValue(defaultValue).
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+
+---*/
+var first = 0;
+var second = 0;
+function* g() {
+ first += 1;
+ yield;
+ second += 1;
+};
+
+var iterCount = 0;
+
+for (var [[,] = g()] of [[]]) {
+ assert.sameValue(first, 1);
+ assert.sameValue(second, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-elision-iter.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-elision-iter.js
new file mode 100644
index 0000000000..2ad18591b0
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-elision-iter.js
@@ -0,0 +1,64 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-elision-iter.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: BindingElement with array binding pattern and initializer is not used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ 1. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ [...]
+ e. Else,
+ i. Let v be IteratorValue(next).
+ [...]
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+
+---*/
+var callCount = 0;
+function* g() {
+ callCount += 1;
+};
+
+var iterCount = 0;
+
+for (var [[,] = g()] of [[[]]]) {
+ assert.sameValue(callCount, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-empty-init.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-empty-init.js
new file mode 100644
index 0000000000..048e325a0f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-empty-init.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-empty-init.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: BindingElement with array binding pattern and initializer is used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ [...]
+ 2. If iteratorRecord.[[done]] is true, let v be undefined.
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be ? GetValue(defaultValue).
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+
+---*/
+var initCount = 0;
+var iterCount = 0;
+var iter = function*() { iterCount += 1; }();
+
+var iterCount = 0;
+
+for (var [[] = function() { initCount += 1; return iter; }()] of [[]]) {
+ assert.sameValue(initCount, 1);
+ assert.sameValue(iterCount, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-empty-iter.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-empty-iter.js
new file mode 100644
index 0000000000..93d9bbf8d3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-empty-iter.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-empty-iter.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: BindingElement with array binding pattern and initializer is not used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ 1. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ [...]
+ e. Else,
+ i. Let v be IteratorValue(next).
+ [...]
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+var initCount = 0;
+
+var iterCount = 0;
+
+for (var [[] = function() { initCount += 1; }()] of [[[23]]]) {
+ assert.sameValue(initCount, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-rest-init.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-rest-init.js
new file mode 100644
index 0000000000..7cf152aead
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-rest-init.js
@@ -0,0 +1,64 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-rest-init.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: BindingElement with array binding pattern and initializer is used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ [...]
+ 2. If iteratorRecord.[[done]] is true, let v be undefined.
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be ? GetValue(defaultValue).
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+var values = [2, 1, 3];
+
+var iterCount = 0;
+
+for (var [[...x] = values] of [[]]) {
+ assert(Array.isArray(x));
+ assert.sameValue(x[0], 2);
+ assert.sameValue(x[1], 1);
+ assert.sameValue(x[2], 3);
+ assert.sameValue(x.length, 3);
+ assert.notSameValue(x, values);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-rest-iter.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-rest-iter.js
new file mode 100644
index 0000000000..1c2e600c19
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-rest-iter.js
@@ -0,0 +1,67 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-rest-iter.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: BindingElement with array binding pattern and initializer is not used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ 1. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ [...]
+ e. Else,
+ i. Let v be IteratorValue(next).
+ [...]
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+var values = [2, 1, 3];
+var initCount = 0;
+
+var iterCount = 0;
+
+for (var [[...x] = function() { initCount += 1; }()] of [[values]]) {
+ assert(Array.isArray(x));
+ assert.sameValue(x[0], 2);
+ assert.sameValue(x[1], 1);
+ assert.sameValue(x[2], 3);
+ assert.sameValue(x.length, 3);
+ assert.notSameValue(x, values);
+ assert.sameValue(initCount, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-val-null.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-val-null.js
new file mode 100644
index 0000000000..9ad7b4bf02
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-ary-val-null.js
@@ -0,0 +1,61 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-ary-val-null.case
+// - src/dstr-binding/error/for-of-var.template
+/*---
+description: Nested array destructuring with a null value (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPattern Initializeropt
+
+ 1. If iteratorRecord.[[done]] is false, then
+ [...]
+ e. Else
+ i. Let v be IteratorValue(next).
+ [...]
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+
+ 13.3.3.5 Runtime Semantics: BindingInitialization
+
+ BindingPattern : ArrayBindingPattern
+
+ 1. Let iterator be GetIterator(value).
+ 2. ReturnIfAbrupt(iterator).
+---*/
+
+assert.throws(TypeError, function() {
+ for (var [[x]] of [[null]]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-exhausted.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-exhausted.js
new file mode 100644
index 0000000000..fb414ef378
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-exhausted.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-exhausted.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Destructuring initializer with an exhausted iterator (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v).
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (var [x = 23] of [[]]) {
+ assert.sameValue(x, 23);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-fn-name-arrow.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-fn-name-arrow.js
new file mode 100644
index 0000000000..e9e4b06253
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-fn-name-arrow.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-fn-name-arrow.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: SingleNameBinding does assign name to arrow functions (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v).
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (var [arrow = () => {}] of [[]]) {
+ assert.sameValue(arrow.name, 'arrow');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-fn-name-class.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-fn-name-class.js
new file mode 100644
index 0000000000..3c3f837137
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-fn-name-class.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-fn-name-class.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: SingleNameBinding assigns `name` to "anonymous" classes (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v).
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (var [cls = class {}, xCls = class X {}, xCls2 = class { static name() {} }] of [[]]) {
+ assert.sameValue(cls.name, 'cls');
+ assert.notSameValue(xCls.name, 'xCls');
+ assert.notSameValue(xCls2.name, 'xCls2');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-fn-name-cover.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-fn-name-cover.js
new file mode 100644
index 0000000000..d9aa65af14
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-fn-name-cover.js
@@ -0,0 +1,61 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-fn-name-cover.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: SingleNameBinding does assign name to "anonymous" functions "through" cover grammar (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v).
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (var [cover = (function () {}), xCover = (0, function() {})] of [[]]) {
+ assert.sameValue(cover.name, 'cover');
+ assert.notSameValue(xCover.name, 'xCover');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-fn-name-fn.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-fn-name-fn.js
new file mode 100644
index 0000000000..fda2eb92cd
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-fn-name-fn.js
@@ -0,0 +1,61 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-fn-name-fn.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: SingleNameBinding assigns name to "anonymous" functions (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v).
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (var [fn = function () {}, xFn = function x() {}] of [[]]) {
+ assert.sameValue(fn.name, 'fn');
+ assert.notSameValue(xFn.name, 'xFn');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-fn-name-gen.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-fn-name-gen.js
new file mode 100644
index 0000000000..aff711e0a8
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-fn-name-gen.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-fn-name-gen.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: SingleNameBinding assigns name to "anonymous" generator functions (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v).
+ 8. Return InitializeReferencedBinding(lhs, v).
+
+---*/
+
+var iterCount = 0;
+
+for (var [gen = function* () {}, xGen = function* x() {}] of [[]]) {
+ assert.sameValue(gen.name, 'gen');
+ assert.notSameValue(xGen.name, 'xGen');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-hole.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-hole.js
new file mode 100644
index 0000000000..912d08c43e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-hole.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-hole.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Destructuring initializer with a "hole" (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+ SingleNameBinding : BindingIdentifier Initializeropt
+ [...] 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v). 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (var [x = 23] of [[,]]) {
+ assert.sameValue(x, 23);
+ // another statement
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-skipped.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-skipped.js
new file mode 100644
index 0000000000..c6c0dea8a8
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-skipped.js
@@ -0,0 +1,64 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-skipped.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Destructuring initializer is not evaluated when value is not `undefined` (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v).
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+var initCount = 0;
+function counter() {
+ initCount += 1;
+}
+
+var iterCount = 0;
+
+for (var [w = counter(), x = counter(), y = counter(), z = counter()] of [[null, 0, false, '']]) {
+ assert.sameValue(w, null);
+ assert.sameValue(x, 0);
+ assert.sameValue(y, false);
+ assert.sameValue(z, '');
+ assert.sameValue(initCount, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-throws.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-throws.js
new file mode 100644
index 0000000000..87515760c3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-throws.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-throws.case
+// - src/dstr-binding/error/for-of-var.template
+/*---
+description: Destructuring initializer returns an abrupt completion (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+---*/
+
+assert.throws(Test262Error, function() {
+ for (var [x = (function() { throw new Test262Error(); })()] of [[undefined]]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-undef.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-undef.js
new file mode 100644
index 0000000000..037cbc91a8
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-undef.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-undef.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Destructuring initializer with an undefined value (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ [...]
+ 7. If environment is undefined, return PutValue(lhs, v).
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (var [x = 23] of [[undefined]]) {
+ assert.sameValue(x, 23);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-unresolvable.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-unresolvable.js
new file mode 100644
index 0000000000..54ad3a10ff
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-unresolvable.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-init-unresolvable.case
+// - src/dstr-binding/error/for-of-var.template
+/*---
+description: Destructuring initializer is an unresolvable reference (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+
+ 6.2.3.1 GetValue (V)
+
+ 1. ReturnIfAbrupt(V).
+ 2. If Type(V) is not Reference, return V.
+ 3. Let base be GetBase(V).
+ 4. If IsUnresolvableReference(V), throw a ReferenceError exception.
+---*/
+
+assert.throws(ReferenceError, function() {
+ for (var [ x = unresolvableReference ] of [[]]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-iter-complete.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-iter-complete.js
new file mode 100644
index 0000000000..0b3349f91f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-iter-complete.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-iter-complete.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: SingleNameBinding when value iteration completes (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (var [x] of [[]]) {
+ assert.sameValue(x, undefined);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-iter-done.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-iter-done.js
new file mode 100644
index 0000000000..cbfae7148d
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-iter-done.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-iter-done.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: SingleNameBinding when value iteration was completed previously (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ [...]
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (var [_, x] of [[]]) {
+ assert.sameValue(x, undefined);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-iter-step-err.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-iter-step-err.js
new file mode 100644
index 0000000000..919712dde1
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-iter-step-err.js
@@ -0,0 +1,61 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-iter-step-err.case
+// - src/dstr-binding/error/for-of-var.template
+/*---
+description: Error forwarding when IteratorStep returns an abrupt completion (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+
+---*/
+var g = {};
+g[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ throw new Test262Error();
+ }
+ };
+};
+
+assert.throws(Test262Error, function() {
+ for (var [x] of [g]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-iter-val-array-prototype.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-iter-val-array-prototype.js
new file mode 100644
index 0000000000..7bc52580ad
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-iter-val-array-prototype.js
@@ -0,0 +1,78 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-iter-val-array-prototype.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Array destructuring uses overriden Array.prototype[Symbol.iterator] (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializer_opt
+
+ 1. Let bindingId be StringValue of BindingIdentifier.
+ 2. Let lhs be ? ResolveBinding(bindingId, environment).
+ 3. If iteratorRecord.[[Done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord).
+ b. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[Done]] to true.
+ e. Else,
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ iii. ReturnIfAbrupt(v).
+ [...]
+ 7. Return InitializeReferencedBinding(lhs, v).
+
+---*/
+Array.prototype[Symbol.iterator] = function* () {
+ if (this.length > 0) {
+ yield this[0];
+ }
+ if (this.length > 1) {
+ yield this[1];
+ }
+ if (this.length > 2) {
+ yield 42;
+ }
+};
+
+var iterCount = 0;
+
+for (var [x, y, z] of [[1, 2, 3]]) {
+ assert.sameValue(x, 1);
+ assert.sameValue(y, 2);
+ assert.sameValue(z, 42);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-iter-val-err.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-iter-val-err.js
new file mode 100644
index 0000000000..ff562dc6b5
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-iter-val-err.js
@@ -0,0 +1,72 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-iter-val-err.case
+// - src/dstr-binding/error/for-of-var.template
+/*---
+description: Error forwarding when IteratorValue returns an abrupt completion (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set iteratorRecord.[[done]] to
+ true.
+ iii. ReturnIfAbrupt(v).
+
+---*/
+var poisonedValue = Object.defineProperty({}, 'value', {
+ get: function() {
+ throw new Test262Error();
+ }
+});
+var g = {};
+g[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return poisonedValue;
+ }
+ };
+};
+
+assert.throws(Test262Error, function() {
+ for (var [x] of [g]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-iter-val.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-iter-val.js
new file mode 100644
index 0000000000..e85402c55f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-id-iter-val.js
@@ -0,0 +1,68 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-id-iter-val.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: SingleNameBinding when value iteration was completed previously (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (var [x, y, z] of [[1, 2, 3]]) {
+ assert.sameValue(x, 1);
+ assert.sameValue(y, 2);
+ assert.sameValue(z, 3);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-obj-id-init.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-obj-id-init.js
new file mode 100644
index 0000000000..54993d3226
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-obj-id-init.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-obj-id-init.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: BindingElement with object binding pattern and initializer is used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ [...]
+ 2. If iteratorRecord.[[done]] is true, let v be undefined.
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be ? GetValue(defaultValue).
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+
+var iterCount = 0;
+
+for (var [{ x, y, z } = { x: 44, y: 55, z: 66 }] of [[]]) {
+ assert.sameValue(x, 44);
+ assert.sameValue(y, 55);
+ assert.sameValue(z, 66);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-obj-id.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-obj-id.js
new file mode 100644
index 0000000000..ac5579dfa9
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-obj-id.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-obj-id.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: BindingElement with object binding pattern and initializer is not used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ [...]
+ 2. If iteratorRecord.[[done]] is true, let v be undefined.
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be ? GetValue(defaultValue).
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+
+var iterCount = 0;
+
+for (var [{ x, y, z } = { x: 44, y: 55, z: 66 }] of [[{ x: 11, y: 22, z: 33 }]]) {
+ assert.sameValue(x, 11);
+ assert.sameValue(y, 22);
+ assert.sameValue(z, 33);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-obj-prop-id-init.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-obj-prop-id-init.js
new file mode 100644
index 0000000000..ec4268c041
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-obj-prop-id-init.js
@@ -0,0 +1,70 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-obj-prop-id-init.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: BindingElement with object binding pattern and initializer is used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ [...]
+ 2. If iteratorRecord.[[done]] is true, let v be undefined.
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be ? GetValue(defaultValue).
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+
+var iterCount = 0;
+
+for (var [{ u: v, w: x, y: z } = { u: 444, w: 555, y: 666 }] of [[]]) {
+ assert.sameValue(v, 444);
+ assert.sameValue(x, 555);
+ assert.sameValue(z, 666);
+
+ assert.throws(ReferenceError, function() {
+ u;
+ });
+ assert.throws(ReferenceError, function() {
+ w;
+ });
+ assert.throws(ReferenceError, function() {
+ y;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-obj-prop-id.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-obj-prop-id.js
new file mode 100644
index 0000000000..7e2679764d
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-obj-prop-id.js
@@ -0,0 +1,70 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-obj-prop-id.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: BindingElement with object binding pattern and initializer is not used (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPatternInitializer opt
+
+ [...]
+ 2. If iteratorRecord.[[done]] is true, let v be undefined.
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be ? GetValue(defaultValue).
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+---*/
+
+var iterCount = 0;
+
+for (var [{ u: v, w: x, y: z } = { u: 444, w: 555, y: 666 }] of [[{ u: 777, w: 888, y: 999 }]]) {
+ assert.sameValue(v, 777);
+ assert.sameValue(x, 888);
+ assert.sameValue(z, 999);
+
+ assert.throws(ReferenceError, function() {
+ u;
+ });
+ assert.throws(ReferenceError, function() {
+ w;
+ });
+ assert.throws(ReferenceError, function() {
+ y;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-obj-val-null.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-obj-val-null.js
new file mode 100644
index 0000000000..2d60795965
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-obj-val-null.js
@@ -0,0 +1,61 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-obj-val-null.case
+// - src/dstr-binding/error/for-of-var.template
+/*---
+description: Nested object destructuring with a null value (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPattern Initializeropt
+
+ 1. If iteratorRecord.[[done]] is false, then
+ [...]
+ e. Else
+ i. Let v be IteratorValue(next).
+ [...]
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+
+ 13.3.3.5 Runtime Semantics: BindingInitialization
+
+ BindingPattern : ObjectBindingPattern
+
+ 1. Let valid be RequireObjectCoercible(value).
+ 2. ReturnIfAbrupt(valid).
+---*/
+
+assert.throws(TypeError, function() {
+ for (var [{ x }] of [[null]]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-obj-val-undef.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-obj-val-undef.js
new file mode 100644
index 0000000000..20784131d5
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elem-obj-val-undef.js
@@ -0,0 +1,61 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elem-obj-val-undef.case
+// - src/dstr-binding/error/for-of-var.template
+/*---
+description: Nested object destructuring with a value of `undefined` (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingElement : BindingPattern Initializeropt
+
+ 1. If iteratorRecord.[[done]] is false, then
+ [...]
+ e. Else
+ i. Let v be IteratorValue(next).
+ [...]
+ 4. Return the result of performing BindingInitialization of BindingPattern
+ with v and environment as the arguments.
+
+ 13.3.3.5 Runtime Semantics: BindingInitialization
+
+ BindingPattern : ObjectBindingPattern
+
+ 1. Let valid be RequireObjectCoercible(value).
+ 2. ReturnIfAbrupt(valid).
+---*/
+
+assert.throws(TypeError, function() {
+ for (var [{ x }] of [[]]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elision-exhausted.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elision-exhausted.js
new file mode 100644
index 0000000000..89d53d7e2c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elision-exhausted.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elision-exhausted.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Elision accepts exhausted iterator (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ ArrayBindingPattern : [ Elision ]
+
+ 1. Return the result of performing
+ IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord
+ as the argument.
+
+ 12.14.5.3 Runtime Semantics: IteratorDestructuringAssignmentEvaluation
+
+ Elision : ,
+
+ 1. If iteratorRecord.[[done]] is false, then
+ [...]
+ 2. Return NormalCompletion(empty).
+
+---*/
+var iter = function*() {}();
+iter.next();
+
+var iterCount = 0;
+
+for (var [,] of [iter]) {
+
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elision-iter-close.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elision-iter-close.js
new file mode 100644
index 0000000000..b3bafbb48b
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elision-iter-close.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elision-iter-close.case
+// - src/dstr-binding/iter-close/for-of-var.template
+/*---
+description: The iterator is properly consumed by the destructuring pattern (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+---*/
+const iter = (function* () {
+ yield;
+ yield;
+})();
+
+
+function fn() {
+ for (var [,] of [iter]) {
+ return;
+ }
+}
+
+fn();
+
+assert.sameValue(iter.next().done, true, 'iteration occurred as expected');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elision-step-err.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elision-step-err.js
new file mode 100644
index 0000000000..472c07b379
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elision-step-err.js
@@ -0,0 +1,68 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elision-step-err.case
+// - src/dstr-binding/error/for-of-var.template
+/*---
+description: Elision advances iterator and forwards abrupt completions (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ ArrayBindingPattern : [ Elision ]
+
+ 1. Return the result of performing
+ IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord
+ as the argument.
+
+ 12.14.5.3 Runtime Semantics: IteratorDestructuringAssignmentEvaluation
+
+ Elision : ,
+
+ 1. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+
+---*/
+var following = 0;
+var iter =function* () {
+ throw new Test262Error();
+ following += 1;
+}();
+
+assert.throws(Test262Error, function() {
+ for (var [,] of [iter]) {
+ return;
+ }
+});
+
+iter.next();
+assert.sameValue(following, 0, 'Iterator was properly closed.');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elision.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elision.js
new file mode 100644
index 0000000000..825866ae24
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-elision.js
@@ -0,0 +1,74 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-elision.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Elision advances iterator (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ ArrayBindingPattern : [ Elision ]
+
+ 1. Return the result of performing
+ IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord
+ as the argument.
+
+ 12.14.5.3 Runtime Semantics: IteratorDestructuringAssignmentEvaluation
+
+ Elision : ,
+
+ 1. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ 2. Return NormalCompletion(empty).
+
+---*/
+var first = 0;
+var second = 0;
+function* g() {
+ first += 1;
+ yield;
+ second += 1;
+};
+
+var iterCount = 0;
+
+for (var [,] of [g()]) {
+ assert.sameValue(first, 1);
+ assert.sameValue(second, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-empty.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-empty.js
new file mode 100644
index 0000000000..5f231ae680
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-empty.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-empty.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: No iteration occurs for an "empty" array binding pattern (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ ArrayBindingPattern : [ ]
+
+ 1. Return NormalCompletion(empty).
+
+---*/
+var iterations = 0;
+var iter = function*() {
+ iterations += 1;
+}();
+
+var iterCount = 0;
+
+for (var [] of [iter]) {
+ assert.sameValue(iterations, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-init-err.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-init-err.js
new file mode 100644
index 0000000000..c46e67f5cc
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-init-err.js
@@ -0,0 +1,18 @@
+// |reftest| error:SyntaxError
+// Copyright (C) 2019 Aleksey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-iteration-statements
+description: >
+ Initializer is not allowed in head's ForBinding position.
+info: |
+ IterationStatement:
+ for (var ForBinding of AssignmentExpression) Statement
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for (var [x] = 1 of []) {}
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-ary-elem.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-ary-elem.js
new file mode 100644
index 0000000000..796759d802
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-ary-elem.js
@@ -0,0 +1,81 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-ary-elem.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Rest element containing an array BindingElementList pattern (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingRestElement : ... BindingPattern
+
+ 1. Let A be ArrayCreate(0).
+ [...]
+ 3. Repeat
+ [...]
+ b. If iteratorRecord.[[done]] is true, then
+ i. Return the result of performing BindingInitialization of
+ BindingPattern with A and environment as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ e. Else,
+ [...]
+ i. Let v be IteratorValue(next).
+ ii. If v is an abrupt completion, set
+ iteratorRecord.[[done]] to true.
+ iii. ReturnIfAbrupt(v).
+ 5. If iteratorRecord.[[done]] is true, let v be undefined.
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (var [...[x, y, z]] of [[3, 4, 5]]) {
+ assert.sameValue(x, 3);
+ assert.sameValue(y, 4);
+ assert.sameValue(z, 5);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-ary-elision.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-ary-elision.js
new file mode 100644
index 0000000000..ab25275749
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-ary-elision.js
@@ -0,0 +1,87 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-ary-elision.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Rest element containing an elision (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingRestElement : ... BindingPattern
+
+ 1. Let A be ArrayCreate(0).
+ [...]
+ 3. Repeat
+ [...]
+ b. If iteratorRecord.[[done]] is true, then
+ i. Return the result of performing BindingInitialization of
+ BindingPattern with A and environment as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ ArrayBindingPattern : [ Elision ]
+
+ 1. Return the result of performing
+ IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord
+ as the argument.
+
+ 12.14.5.3 Runtime Semantics: IteratorDestructuringAssignmentEvaluation
+
+ Elision : ,
+
+ 1. If iteratorRecord.[[done]] is false, then
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, set iteratorRecord.[[done]] to true.
+ 2. Return NormalCompletion(empty).
+
+---*/
+var first = 0;
+var second = 0;
+function* g() {
+ first += 1;
+ yield;
+ second += 1;
+};
+
+var iterCount = 0;
+
+for (var [...[,]] of [g()]) {
+ assert.sameValue(first, 1);
+ assert.sameValue(second, 1);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-ary-empty.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-ary-empty.js
new file mode 100644
index 0000000000..8888d31dde
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-ary-empty.js
@@ -0,0 +1,70 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-ary-empty.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Rest element containing an "empty" array pattern (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingRestElement : ... BindingPattern
+
+ 1. Let A be ArrayCreate(0).
+ [...]
+ 3. Repeat
+ [...]
+ b. If iteratorRecord.[[done]] is true, then
+ i. Return the result of performing BindingInitialization of
+ BindingPattern with A and environment as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ ArrayBindingPattern : [ ]
+
+ 1. Return NormalCompletion(empty).
+
+---*/
+var iterations = 0;
+var iter = function*() {
+ iterations += 1;
+}();
+
+var iterCount = 0;
+
+for (var [...[]] of [iter]) {
+ assert.sameValue(iterations, 1);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-ary-rest.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-ary-rest.js
new file mode 100644
index 0000000000..25a6d7b401
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-ary-rest.js
@@ -0,0 +1,66 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-ary-rest.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Rest element containing a rest element (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingRestElement : ... BindingPattern
+
+ 1. Let A be ArrayCreate(0).
+ [...]
+ 3. Repeat
+ [...]
+ b. If iteratorRecord.[[done]] is true, then
+ i. Return the result of performing BindingInitialization of
+ BindingPattern with A and environment as the arguments.
+ [...]
+---*/
+var values = [1, 2, 3];
+
+var iterCount = 0;
+
+for (var [...[...x]] of [values]) {
+ assert(Array.isArray(x));
+ assert.sameValue(x.length, 3);
+ assert.sameValue(x[0], 1);
+ assert.sameValue(x[1], 2);
+ assert.sameValue(x[2], 3);
+ assert.notSameValue(x, values);
+
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-direct.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-direct.js
new file mode 100644
index 0000000000..91ada24c57
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-direct.js
@@ -0,0 +1,61 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-id-direct.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Lone rest element (direct binding) (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+includes: [compareArray.js]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ Runtime Semantics: IteratorBindingInitialization
+
+ BindingRestElement : ... BindingIdentifier
+
+ [...]
+ 2. Let A be ! ArrayCreate(0).
+ 3. Let n be 0.
+ 4. Repeat,
+ [...]
+ f. Perform ! CreateDataPropertyOrThrow(A, ! ToString(n), nextValue).
+ g. Set n to n + 1.
+
+---*/
+
+var iterCount = 0;
+
+for (var [...x] of [[1]]) {
+ assert(Array.isArray(x));
+ assert.compareArray(x, [1]);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-elision-next-err.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-elision-next-err.js
new file mode 100644
index 0000000000..35e56ada55
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-elision-next-err.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-id-elision-next-err.case
+// - src/dstr-binding/error/for-of-var.template
+/*---
+description: Rest element following elision elements (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+ ArrayBindingPattern : [ Elisionopt BindingRestElement ]
+ 1. If Elision is present, then
+ a. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of Elision with
+ iteratorRecord as the argument.
+ b. ReturnIfAbrupt(status).
+ 2. Return the result of performing IteratorBindingInitialization for
+ BindingRestElement with iteratorRecord and environment as arguments.
+
+---*/
+var iter = (function*() { throw new Test262Error(); })();
+
+assert.throws(Test262Error, function() {
+ for (var [, ...x] of [iter]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-elision.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-elision.js
new file mode 100644
index 0000000000..171d45bd62
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-elision.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-id-elision.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Rest element following elision elements (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+ ArrayBindingPattern : [ Elisionopt BindingRestElement ]
+ 1. If Elision is present, then
+ a. Let status be the result of performing
+ IteratorDestructuringAssignmentEvaluation of Elision with
+ iteratorRecord as the argument.
+ b. ReturnIfAbrupt(status).
+ 2. Return the result of performing IteratorBindingInitialization for
+ BindingRestElement with iteratorRecord and environment as arguments.
+---*/
+var values = [1, 2, 3, 4, 5];
+
+var iterCount = 0;
+
+for (var [ , , ...x] of [values]) {
+ assert(Array.isArray(x));
+ assert.sameValue(x.length, 3);
+ assert.sameValue(x[0], 3);
+ assert.sameValue(x[1], 4);
+ assert.sameValue(x[2], 5);
+ assert.notSameValue(x, values);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-exhausted.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-exhausted.js
new file mode 100644
index 0000000000..da5af0d7cc
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-exhausted.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-id-exhausted.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: RestElement applied to an exhausted iterator (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+ BindingRestElement : ... BindingIdentifier
+ 1. Let lhs be ResolveBinding(StringValue of BindingIdentifier,
+ environment).
+ 2. ReturnIfAbrupt(lhs). 3. Let A be ArrayCreate(0). 4. Let n=0. 5. Repeat,
+ [...]
+ b. If iteratorRecord.[[done]] is true, then
+ i. If environment is undefined, return PutValue(lhs, A).
+ ii. Return InitializeReferencedBinding(lhs, A).
+
+---*/
+
+var iterCount = 0;
+
+for (var [, , ...x] of [[1, 2]]) {
+ assert(Array.isArray(x));
+ assert.sameValue(x.length, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-iter-close.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-iter-close.js
new file mode 100644
index 0000000000..dbff7e55b8
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-iter-close.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-id-iter-close.case
+// - src/dstr-binding/iter-close/for-of-var.template
+/*---
+description: The iterator is properly consumed by the destructuring pattern (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+---*/
+const iter = (function* () {
+ yield;
+ yield;
+})();
+
+
+function fn() {
+ for (var [...x] of [iter]) {
+ return;
+ }
+}
+
+fn();
+
+assert.sameValue(iter.next().done, true, 'iteration occurred as expected');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-iter-step-err.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-iter-step-err.js
new file mode 100644
index 0000000000..d243017b82
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-iter-step-err.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-id-iter-step-err.case
+// - src/dstr-binding/error/for-of-var.template
+/*---
+description: Error forwarding when IteratorStep returns an abrupt completion (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+ BindingRestElement : ... BindingIdentifier
+ 1. Let lhs be ResolveBinding(StringValue of BindingIdentifier,
+ environment).
+ 2. ReturnIfAbrupt(lhs). 3. Let A be ArrayCreate(0). 4. Let n=0. 5. Repeat,
+ a. If iteratorRecord.[[done]] is false,
+ i. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ ii. If next is an abrupt completion, set iteratorRecord.[[done]] to
+ true.
+ iii. ReturnIfAbrupt(next).
+
+---*/
+var first = 0;
+var second = 0;
+var iter = function*() {
+ first += 1;
+ throw new Test262Error();
+ second += 1;
+}();
+
+assert.throws(Test262Error, function() {
+ for (var [...x] of [iter]) {
+ return;
+ }
+});
+
+iter.next();
+assert.sameValue(first, 1);
+assert.sameValue(second, 0, 'Iterator is closed following abrupt completion.');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-iter-val-err.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-iter-val-err.js
new file mode 100644
index 0000000000..4ef4dd47cb
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id-iter-val-err.js
@@ -0,0 +1,67 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-id-iter-val-err.case
+// - src/dstr-binding/error/for-of-var.template
+/*---
+description: Error forwarding when IteratorValue returns an abrupt completion (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [Symbol.iterator, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+ BindingRestElement : ... BindingIdentifier
+ 1. Let lhs be ResolveBinding(StringValue of BindingIdentifier,
+ environment).
+ 2. ReturnIfAbrupt(lhs). 3. Let A be ArrayCreate(0). 4. Let n=0. 5. Repeat,
+ [...]
+ c. Let nextValue be IteratorValue(next).
+ d. If nextValue is an abrupt completion, set iteratorRecord.[[done]] to
+ true.
+ e. ReturnIfAbrupt(nextValue).
+
+---*/
+var poisonedValue = Object.defineProperty({}, 'value', {
+ get: function() {
+ throw new Test262Error();
+ }
+});
+var iter = {};
+iter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return poisonedValue;
+ }
+ };
+};
+
+assert.throws(Test262Error, function() {
+ for (var [...x] of [iter]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id.js
new file mode 100644
index 0000000000..26f87e48ac
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-id.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-id.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Lone rest element (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+ BindingRestElement : ... BindingIdentifier
+ [...] 3. Let A be ArrayCreate(0). [...] 5. Repeat
+ [...]
+ f. Let status be CreateDataProperty(A, ToString (n), nextValue).
+ [...]
+---*/
+var values = [1, 2, 3];
+
+var iterCount = 0;
+
+for (var [...x] of [values]) {
+ assert(Array.isArray(x));
+ assert.sameValue(x.length, 3);
+ assert.sameValue(x[0], 1);
+ assert.sameValue(x[1], 2);
+ assert.sameValue(x[2], 3);
+ assert.notSameValue(x, values);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-init-ary.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-init-ary.js
new file mode 100644
index 0000000000..f1e04d9601
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-init-ary.js
@@ -0,0 +1,55 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-init-ary.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Rest element (nested array pattern) does not support initializer (for-of 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 ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+ ArrayBindingPattern[Yield] :
+ [ Elisionopt BindingRestElement[?Yield]opt ]
+ [ BindingElementList[?Yield] ]
+ [ BindingElementList[?Yield] , Elisionopt BindingRestElement[?Yield]opt ]
+---*/
+$DONOTEVALUATE();
+
+var iterCount = 0;
+
+for (var [...[ x ] = []] of [[]]) {
+
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-init-id.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-init-id.js
new file mode 100644
index 0000000000..fd2ac5b50e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-init-id.js
@@ -0,0 +1,55 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-init-id.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Rest element (identifier) does not support initializer (for-of 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 ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+ ArrayBindingPattern[Yield] :
+ [ Elisionopt BindingRestElement[?Yield]opt ]
+ [ BindingElementList[?Yield] ]
+ [ BindingElementList[?Yield] , Elisionopt BindingRestElement[?Yield]opt ]
+---*/
+$DONOTEVALUATE();
+
+var iterCount = 0;
+
+for (var [...x = []] of [[]]) {
+
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-init-obj.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-init-obj.js
new file mode 100644
index 0000000000..233d21059e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-init-obj.js
@@ -0,0 +1,55 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-init-obj.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Rest element (nested object pattern) does not support initializer (for-of 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 ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+ ArrayBindingPattern[Yield] :
+ [ Elisionopt BindingRestElement[?Yield]opt ]
+ [ BindingElementList[?Yield] ]
+ [ BindingElementList[?Yield] , Elisionopt BindingRestElement[?Yield]opt ]
+---*/
+$DONOTEVALUATE();
+
+var iterCount = 0;
+
+for (var [...{ x } = []] of [[]]) {
+
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-not-final-ary.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-not-final-ary.js
new file mode 100644
index 0000000000..e86e6dcb97
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-not-final-ary.js
@@ -0,0 +1,55 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-not-final-ary.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Rest element (array binding pattern) may not be followed by any element (for-of 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 ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+ ArrayBindingPattern[Yield] :
+ [ Elisionopt BindingRestElement[?Yield]opt ]
+ [ BindingElementList[?Yield] ]
+ [ BindingElementList[?Yield] , Elisionopt BindingRestElement[?Yield]opt ]
+---*/
+$DONOTEVALUATE();
+
+var iterCount = 0;
+
+for (var [...[x], y] of [[1, 2, 3]]) {
+
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-not-final-id.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-not-final-id.js
new file mode 100644
index 0000000000..e1d647b8d6
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-not-final-id.js
@@ -0,0 +1,55 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-not-final-id.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Rest element (identifier) may not be followed by any element (for-of 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 ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+ ArrayBindingPattern[Yield] :
+ [ Elisionopt BindingRestElement[?Yield]opt ]
+ [ BindingElementList[?Yield] ]
+ [ BindingElementList[?Yield] , Elisionopt BindingRestElement[?Yield]opt ]
+---*/
+$DONOTEVALUATE();
+
+var iterCount = 0;
+
+for (var [...x, y] of [[1, 2, 3]]) {
+
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-not-final-obj.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-not-final-obj.js
new file mode 100644
index 0000000000..cbc74de10d
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-not-final-obj.js
@@ -0,0 +1,55 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-not-final-obj.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Rest element (object binding pattern) may not be followed by any element (for-of 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 ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+ ArrayBindingPattern[Yield] :
+ [ Elisionopt BindingRestElement[?Yield]opt ]
+ [ BindingElementList[?Yield] ]
+ [ BindingElementList[?Yield] , Elisionopt BindingRestElement[?Yield]opt ]
+---*/
+$DONOTEVALUATE();
+
+var iterCount = 0;
+
+for (var [...{ x }, y] of [[1, 2, 3]]) {
+
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-obj-id.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-obj-id.js
new file mode 100644
index 0000000000..01b6daecdd
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-obj-id.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-obj-id.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Rest element containing an object binding pattern (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingRestElement : ... BindingPattern
+
+ 1. Let A be ArrayCreate(0).
+ [...]
+ 3. Repeat
+ [...]
+ b. If iteratorRecord.[[done]] is true, then
+ i. Return the result of performing BindingInitialization of
+ BindingPattern with A and environment as the arguments.
+ [...]
+---*/
+
+var iterCount = 0;
+
+for (var [...{ length }] of [[1, 2, 3]]) {
+ assert.sameValue(length, 3);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-obj-prop-id.js b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-obj-prop-id.js
new file mode 100644
index 0000000000..477f4c5e9e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-ary-ptrn-rest-obj-prop-id.js
@@ -0,0 +1,66 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/ary-ptrn-rest-obj-prop-id.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Rest element containing an object binding pattern (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.6 Runtime Semantics: IteratorBindingInitialization
+
+ BindingRestElement : ... BindingPattern
+
+ 1. Let A be ArrayCreate(0).
+ [...]
+ 3. Repeat
+ [...]
+ b. If iteratorRecord.[[done]] is true, then
+ i. Return the result of performing BindingInitialization of
+ BindingPattern with A and environment as the arguments.
+ [...]
+---*/
+let length = "outer";
+
+var iterCount = 0;
+
+for (var [...{ 0: v, 1: w, 2: x, 3: y, length: z }] of [[7, 8, 9]]) {
+ assert.sameValue(v, 7);
+ assert.sameValue(w, 8);
+ assert.sameValue(x, 9);
+ assert.sameValue(y, undefined);
+ assert.sameValue(z, 3);
+
+ assert.sameValue(length, "outer", "the length prop is not set as a binding name");
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-init-null.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-init-null.js
new file mode 100644
index 0000000000..f000d07a54
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-init-null.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-init-null.case
+// - src/dstr-binding/error/for-of-var.template
+/*---
+description: Value specifed for object binding pattern must be object coercible (null) (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ Runtime Semantics: BindingInitialization
+
+ ObjectBindingPattern : { }
+
+ 1. Return NormalCompletion(empty).
+---*/
+
+assert.throws(TypeError, function() {
+ for (var {} of [null]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-init-undefined.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-init-undefined.js
new file mode 100644
index 0000000000..3b94ad21fd
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-init-undefined.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-init-undefined.case
+// - src/dstr-binding/error/for-of-var.template
+/*---
+description: Value specifed for object binding pattern must be object coercible (undefined) (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ Runtime Semantics: BindingInitialization
+
+ ObjectBindingPattern : { }
+
+ 1. Return NormalCompletion(empty).
+---*/
+
+assert.throws(TypeError, function() {
+ for (var {} of [undefined]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-empty.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-empty.js
new file mode 100644
index 0000000000..53508700b3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-empty.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-empty.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: No property access occurs for an "empty" object binding pattern (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ Runtime Semantics: BindingInitialization
+
+ ObjectBindingPattern : { }
+
+ 1. Return NormalCompletion(empty).
+---*/
+var accessCount = 0;
+var obj = Object.defineProperty({}, 'attr', {
+ get: function() {
+ accessCount += 1;
+ }
+});
+
+var iterCount = 0;
+
+for (var {} of [obj]) {
+ assert.sameValue(accessCount, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-get-value-err.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-get-value-err.js
new file mode 100644
index 0000000000..1fc9af43c2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-get-value-err.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-get-value-err.case
+// - src/dstr-binding/error/for-of-var.template
+/*---
+description: Error thrown when accessing the corresponding property of the value object (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 4. Let v be GetV(value, propertyName).
+ 5. ReturnIfAbrupt(v).
+---*/
+var poisonedProperty = Object.defineProperty({}, 'poisoned', {
+ get: function() {
+ throw new Test262Error();
+ }
+});
+
+assert.throws(Test262Error, function() {
+ for (var { poisoned } of [poisonedProperty]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-fn-name-arrow.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-fn-name-arrow.js
new file mode 100644
index 0000000000..05332ad39b
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-fn-name-arrow.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-init-fn-name-arrow.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: SingleNameBinding assigns `name` to arrow functions (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ [...]
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ i. Let hasNameProperty be HasOwnProperty(v, "name").
+ ii. ReturnIfAbrupt(hasNameProperty).
+ iii. If hasNameProperty is false, perform SetFunctionName(v,
+ bindingId).
+---*/
+
+var iterCount = 0;
+
+for (var { arrow = () => {} } of [{}]) {
+ assert.sameValue(arrow.name, 'arrow');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-fn-name-class.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-fn-name-class.js
new file mode 100644
index 0000000000..7f8cce3325
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-fn-name-class.js
@@ -0,0 +1,61 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-init-fn-name-class.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: SingleNameBinding assigns `name` to "anonymous" classes (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ [...]
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ i. Let hasNameProperty be HasOwnProperty(v, "name").
+ ii. ReturnIfAbrupt(hasNameProperty).
+ iii. If hasNameProperty is false, perform SetFunctionName(v,
+ bindingId).
+---*/
+
+var iterCount = 0;
+
+for (var { cls = class {}, xCls = class X {}, xCls2 = class { static name() {} } } of [{}]) {
+ assert.sameValue(cls.name, 'cls');
+ assert.notSameValue(xCls.name, 'xCls');
+ assert.notSameValue(xCls2.name, 'xCls2');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-fn-name-cover.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-fn-name-cover.js
new file mode 100644
index 0000000000..b2c855f183
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-fn-name-cover.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-init-fn-name-cover.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: SingleNameBinding assigns `name` to "anonymous" functions "through" cover grammar (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ [...]
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ i. Let hasNameProperty be HasOwnProperty(v, "name").
+ ii. ReturnIfAbrupt(hasNameProperty).
+ iii. If hasNameProperty is false, perform SetFunctionName(v,
+ bindingId).
+---*/
+
+var iterCount = 0;
+
+for (var { cover = (function () {}), xCover = (0, function() {}) } of [{}]) {
+ assert.sameValue(cover.name, 'cover');
+ assert.notSameValue(xCover.name, 'xCover');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-fn-name-fn.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-fn-name-fn.js
new file mode 100644
index 0000000000..98b78fd411
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-fn-name-fn.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-init-fn-name-fn.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: SingleNameBinding assigns name to "anonymous" functions (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ [...]
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ i. Let hasNameProperty be HasOwnProperty(v, "name").
+ ii. ReturnIfAbrupt(hasNameProperty).
+ iii. If hasNameProperty is false, perform SetFunctionName(v,
+ bindingId).
+---*/
+
+var iterCount = 0;
+
+for (var { fn = function () {}, xFn = function x() {} } of [{}]) {
+ assert.sameValue(fn.name, 'fn');
+ assert.notSameValue(xFn.name, 'xFn');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-fn-name-gen.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-fn-name-gen.js
new file mode 100644
index 0000000000..6f7ee71468
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-fn-name-gen.js
@@ -0,0 +1,61 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-init-fn-name-gen.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: SingleNameBinding assigns name to "anonymous" generator functions (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ [...]
+ d. If IsAnonymousFunctionDefinition(Initializer) is true, then
+ i. Let hasNameProperty be HasOwnProperty(v, "name").
+ ii. ReturnIfAbrupt(hasNameProperty).
+ iii. If hasNameProperty is false, perform SetFunctionName(v,
+ bindingId).
+
+---*/
+
+var iterCount = 0;
+
+for (var { gen = function* () {}, xGen = function* x() {} } of [{}]) {
+ assert.sameValue(gen.name, 'gen');
+ assert.notSameValue(xGen.name, 'xGen');
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-skipped.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-skipped.js
new file mode 100644
index 0000000000..b7af3e4968
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-skipped.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-init-skipped.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Destructuring initializer is not evaluated when value is not `undefined` (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ [...]
+ [...]
+---*/
+var initCount = 0;
+function counter() {
+ initCount += 1;
+}
+
+var iterCount = 0;
+
+for (var { w = counter(), x = counter(), y = counter(), z = counter() } of [{ w: null, x: 0, y: false, z: '' }]) {
+ assert.sameValue(w, null);
+ assert.sameValue(x, 0);
+ assert.sameValue(y, false);
+ assert.sameValue(z, '');
+ assert.sameValue(initCount, 0);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-throws.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-throws.js
new file mode 100644
index 0000000000..d6cfe57116
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-throws.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-init-throws.case
+// - src/dstr-binding/error/for-of-var.template
+/*---
+description: Error thrown when evaluating the initializer (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+---*/
+function thrower() {
+ throw new Test262Error();
+}
+
+assert.throws(Test262Error, function() {
+ for (var { x = thrower() } of [{}]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-unresolvable.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-unresolvable.js
new file mode 100644
index 0000000000..273fc8422f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-init-unresolvable.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-init-unresolvable.case
+// - src/dstr-binding/error/for-of-var.template
+/*---
+description: Destructuring initializer is an unresolvable reference (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 6. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+
+ 6.2.3.1 GetValue (V)
+
+ 1. ReturnIfAbrupt(V).
+ 2. If Type(V) is not Reference, return V.
+ 3. Let base be GetBase(V).
+ 4. If IsUnresolvableReference(V), throw a ReferenceError exception.
+---*/
+
+assert.throws(ReferenceError, function() {
+ for (var { x = unresolvableReference } of [{}]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-trailing-comma.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-trailing-comma.js
new file mode 100644
index 0000000000..0f8c247d2d
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-id-trailing-comma.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-id-trailing-comma.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Trailing comma is allowed following BindingPropertyList (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+
+ ObjectBindingPattern[Yield] :
+ { }
+ { BindingPropertyList[?Yield] }
+ { BindingPropertyList[?Yield] , }
+---*/
+
+var iterCount = 0;
+
+for (var { x, } of [{ x: 23 }]) {
+ assert.sameValue(x, 23);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-init-err.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-init-err.js
new file mode 100644
index 0000000000..6d912b28a4
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-init-err.js
@@ -0,0 +1,18 @@
+// |reftest| error:SyntaxError
+// Copyright (C) 2019 Aleksey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-iteration-statements
+description: >
+ Initializer is not allowed in head's ForBinding position.
+info: |
+ IterationStatement:
+ for (var ForBinding of AssignmentExpression) Statement
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for (var {x} = 1 of []) {}
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-list-err.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-list-err.js
new file mode 100644
index 0000000000..c9534bd7d3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-list-err.js
@@ -0,0 +1,56 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-list-err.case
+// - src/dstr-binding/error/for-of-var.template
+/*---
+description: Binding property list evaluation is interrupted by an abrupt completion (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.5 Runtime Semantics: BindingInitialization
+
+ BindingPropertyList : BindingPropertyList , BindingProperty
+
+ 1. Let status be the result of performing BindingInitialization for
+ BindingPropertyList using value and environment as arguments.
+ 2. ReturnIfAbrupt(status).
+---*/
+var initCount = 0;
+function thrower() {
+ throw new Test262Error();
+}
+
+assert.throws(Test262Error, function() {
+ for (var { a, b = thrower(), c = ++initCount } of [{}]) {
+ return;
+ }
+});
+
+assert.sameValue(initCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-ary-init.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-ary-init.js
new file mode 100644
index 0000000000..25ad8096dd
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-ary-init.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-ary-init.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Object binding pattern with "nested" array binding pattern using initializer (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+ 4. Return the result of performing BindingInitialization for BindingPattern
+ passing v and environment as arguments.
+---*/
+
+var iterCount = 0;
+
+for (var { w: [x, y, z] = [4, 5, 6] } of [{}]) {
+ assert.sameValue(x, 4);
+ assert.sameValue(y, 5);
+ assert.sameValue(z, 6);
+
+ assert.throws(ReferenceError, function() {
+ w;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-ary-trailing-comma.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-ary-trailing-comma.js
new file mode 100644
index 0000000000..ede1ac1210
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-ary-trailing-comma.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-ary-trailing-comma.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Trailing comma is allowed following BindingPropertyList (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+
+ ObjectBindingPattern[Yield] :
+ { }
+ { BindingPropertyList[?Yield] }
+ { BindingPropertyList[?Yield] , }
+---*/
+
+var iterCount = 0;
+
+for (var { x: [y], } of [{ x: [45] }]) {
+ assert.sameValue(y,45);
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-ary-value-null.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-ary-value-null.js
new file mode 100644
index 0000000000..1ffcf14f73
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-ary-value-null.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-ary-value-null.case
+// - src/dstr-binding/error/for-of-var.template
+/*---
+description: Object binding pattern with "nested" array binding pattern taking the `null` value (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ [...]
+ 4. Return the result of performing BindingInitialization for BindingPattern
+ passing v and environment as arguments.
+---*/
+
+assert.throws(TypeError, function() {
+ for (var { w: [x, y, z] = [4, 5, 6] } of [{ w: null }]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-ary.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-ary.js
new file mode 100644
index 0000000000..a6ddc5865a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-ary.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-ary.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Object binding pattern with "nested" array binding pattern not using initializer (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ [...]
+ 4. Return the result of performing BindingInitialization for BindingPattern
+ passing v and environment as arguments.
+---*/
+
+var iterCount = 0;
+
+for (var { w: [x, y, z] = [4, 5, 6] } of [{ w: [7, undefined, ] }]) {
+ assert.sameValue(x, 7);
+ assert.sameValue(y, undefined);
+ assert.sameValue(z, undefined);
+
+ assert.throws(ReferenceError, function() {
+ w;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-eval-err.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-eval-err.js
new file mode 100644
index 0000000000..527d6303a1
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-eval-err.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-eval-err.case
+// - src/dstr-binding/error/for-of-var.template
+/*---
+description: Evaluation of property name returns an abrupt completion (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.5 Runtime Semantics: BindingInitialization
+
+ BindingProperty : PropertyName : BindingElement
+
+ 1. Let P be the result of evaluating PropertyName
+ 2. ReturnIfAbrupt(P).
+---*/
+function thrower() {
+ throw new Test262Error();
+}
+
+assert.throws(Test262Error, function() {
+ for (var { [thrower()]: x } of [{}]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id-get-value-err.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id-get-value-err.js
new file mode 100644
index 0000000000..ca4c6e44a0
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id-get-value-err.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-id-get-value-err.case
+// - src/dstr-binding/error/for-of-var.template
+/*---
+description: Error thrown when accessing the corresponding property of the value object (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ BindingElement : BindingPattern Initializeropt
+
+ 1. Let v be GetV(value, propertyName).
+ 2. ReturnIfAbrupt(v).
+---*/
+var initEvalCount = 0;
+var poisonedProperty = Object.defineProperty({}, 'poisoned', {
+ get: function() {
+ throw new Test262Error();
+ }
+});
+
+assert.throws(Test262Error, function() {
+ for (var { poisoned: x = ++initEvalCount } of [poisonedProperty]) {
+ return;
+ }
+});
+
+assert.sameValue(initEvalCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id-init-skipped.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id-init-skipped.js
new file mode 100644
index 0000000000..d6cb0f7c9d
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id-init-skipped.js
@@ -0,0 +1,75 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-id-init-skipped.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Destructuring initializer is not evaluated when value is not `undefined` (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ BindingElement : BindingPattern Initializeropt
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ [...]
+---*/
+var initCount = 0;
+function counter() {
+ initCount += 1;
+}
+
+var iterCount = 0;
+
+for (var { s: t = counter(), u: v = counter(), w: x = counter(), y: z = counter() } of [{ s: null, u: 0, w: false, y: '' }]) {
+ assert.sameValue(t, null);
+ assert.sameValue(v, 0);
+ assert.sameValue(x, false);
+ assert.sameValue(z, '');
+ assert.sameValue(initCount, 0);
+
+ assert.throws(ReferenceError, function() {
+ s;
+ });
+ assert.throws(ReferenceError, function() {
+ u;
+ });
+ assert.throws(ReferenceError, function() {
+ w;
+ });
+ assert.throws(ReferenceError, function() {
+ y;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id-init-throws.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id-init-throws.js
new file mode 100644
index 0000000000..d732cee124
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id-init-throws.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-id-init-throws.case
+// - src/dstr-binding/error/for-of-var.template
+/*---
+description: Error thrown when evaluating the initializer (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ BindingElement : BindingPattern Initializeropt
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+---*/
+function thrower() {
+ throw new Test262Error();
+}
+
+assert.throws(Test262Error, function() {
+ for (var { x: y = thrower() } of [{}]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id-init-unresolvable.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id-init-unresolvable.js
new file mode 100644
index 0000000000..11550ff952
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id-init-unresolvable.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-id-init-unresolvable.case
+// - src/dstr-binding/error/for-of-var.template
+/*---
+description: Destructuring initializer is an unresolvable reference (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ BindingElement : BindingPattern Initializeropt
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+
+ 6.2.3.1 GetValue (V)
+
+ 1. ReturnIfAbrupt(V).
+ 2. If Type(V) is not Reference, return V.
+ 3. Let base be GetBase(V).
+ 4. If IsUnresolvableReference(V), throw a ReferenceError exception.
+---*/
+
+assert.throws(ReferenceError, function() {
+ for (var { x: y = unresolvableReference } of [{}]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id-init.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id-init.js
new file mode 100644
index 0000000000..d8edc4fcdd
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id-init.js
@@ -0,0 +1,56 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-id-init.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Binding as specified via property name, identifier, and initializer (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (var { x: y = 33 } of [{ }]) {
+ assert.sameValue(y, 33);
+ assert.throws(ReferenceError, function() {
+ x;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id-trailing-comma.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id-trailing-comma.js
new file mode 100644
index 0000000000..e8c9fbaff1
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id-trailing-comma.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-id-trailing-comma.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Trailing comma is allowed following BindingPropertyList (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3 Destructuring Binding Patterns
+
+ ObjectBindingPattern[Yield] :
+ { }
+ { BindingPropertyList[?Yield] }
+ { BindingPropertyList[?Yield] , }
+---*/
+
+var iterCount = 0;
+
+for (var { x: y, } of [{ x: 23 }]) {
+ assert.sameValue(y, 23);
+
+ assert.throws(ReferenceError, function() {
+ x;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id.js
new file mode 100644
index 0000000000..fbfb842c58
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-id.js
@@ -0,0 +1,56 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-id.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Binding as specified via property name and identifier (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializeropt
+
+ [...]
+ 8. Return InitializeReferencedBinding(lhs, v).
+---*/
+
+var iterCount = 0;
+
+for (var { x: y } of [{ x: 23 }]) {
+ assert.sameValue(y, 23);
+ assert.throws(ReferenceError, function() {
+ x;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-obj-init.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-obj-init.js
new file mode 100644
index 0000000000..6b148f8351
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-obj-init.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-obj-init.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Object binding pattern with "nested" object binding pattern using initializer (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ a. Let defaultValue be the result of evaluating Initializer.
+ b. Let v be GetValue(defaultValue).
+ c. ReturnIfAbrupt(v).
+ 4. Return the result of performing BindingInitialization for BindingPattern
+ passing v and environment as arguments.
+---*/
+
+var iterCount = 0;
+
+for (var { w: { x, y, z } = { x: 4, y: 5, z: 6 } } of [{ w: undefined }]) {
+ assert.sameValue(x, 4);
+ assert.sameValue(y, 5);
+ assert.sameValue(z, 6);
+
+ assert.throws(ReferenceError, function() {
+ w;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-obj-value-null.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-obj-value-null.js
new file mode 100644
index 0000000000..4f5578046f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-obj-value-null.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-obj-value-null.case
+// - src/dstr-binding/error/for-of-var.template
+/*---
+description: Object binding pattern with "nested" object binding pattern taking the `null` value (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ [...]
+ 4. Return the result of performing BindingInitialization for BindingPattern
+ passing v and environment as arguments.
+---*/
+
+assert.throws(TypeError, function() {
+ for (var { w: { x, y, z } = { x: 4, y: 5, z: 6 } } of [{ w: null }]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-obj-value-undef.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-obj-value-undef.js
new file mode 100644
index 0000000000..1816ef51ba
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-obj-value-undef.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-obj-value-undef.case
+// - src/dstr-binding/error/for-of-var.template
+/*---
+description: Object binding pattern with "nested" object binding pattern taking the `null` value (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ [...]
+ 4. Return the result of performing BindingInitialization for BindingPattern
+ passing v and environment as arguments.
+---*/
+
+assert.throws(TypeError, function() {
+ for (var { w: { x, y, z } = undefined } of [{ }]) {
+ return;
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-obj.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-obj.js
new file mode 100644
index 0000000000..38214fd142
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-prop-obj.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-prop-obj.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Object binding pattern with "nested" object binding pattern not using initializer (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+
+ 13.3.3.7 Runtime Semantics: KeyedBindingInitialization
+
+ [...]
+ 3. If Initializer is present and v is undefined, then
+ [...]
+ 4. Return the result of performing BindingInitialization for BindingPattern
+ passing v and environment as arguments.
+---*/
+
+var iterCount = 0;
+
+for (var { w: { x, y, z } = { x: 4, y: 5, z: 6 } } of [{ w: { x: undefined, z: 7 } }]) {
+ assert.sameValue(x, undefined);
+ assert.sameValue(y, undefined);
+ assert.sameValue(z, 7);
+
+ assert.throws(ReferenceError, function() {
+ w;
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-rest-getter.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-rest-getter.js
new file mode 100644
index 0000000000..a45a39a69b
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-rest-getter.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-rest-getter.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Getter is called when obj is being deconstructed to a rest Object (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+---*/
+var count = 0;
+
+var iterCount = 0;
+
+for (var {...x} of [{ get v() { count++; return 2; } }]) {
+ assert.sameValue(count, 1);
+
+ verifyProperty(x, "v", {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: 2
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-rest-skip-non-enumerable.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-rest-skip-non-enumerable.js
new file mode 100644
index 0000000000..27820d5b91
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-rest-skip-non-enumerable.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-rest-skip-non-enumerable.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Rest object doesn't contain non-enumerable properties (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+---*/
+var o = {a: 3, b: 4};
+Object.defineProperty(o, "x", { value: 4, enumerable: false });
+
+var iterCount = 0;
+
+for (var {...rest} of [o]) {
+ assert.sameValue(rest.x, undefined);
+
+ verifyProperty(rest, "a", {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: 3
+ });
+
+ verifyProperty(rest, "b", {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: 4
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-rest-val-obj.js b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-rest-val-obj.js
new file mode 100644
index 0000000000..b0cec431bd
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/dstr/var-obj-ptrn-rest-val-obj.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/dstr-binding/obj-ptrn-rest-val-obj.case
+// - src/dstr-binding/default/for-of-var.template
+/*---
+description: Rest object contains just unextracted data (for-of statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+includes: [propertyHelper.js]
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+
+ [...]
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 3. Let destructuring be IsDestructuring of lhs.
+ [...]
+ 5. Repeat
+ [...]
+ h. If destructuring is false, then
+ [...]
+ i. Else
+ i. If lhsKind is assignment, then
+ [...]
+ ii. Else if lhsKind is varBinding, then
+ 1. Assert: lhs is a ForBinding.
+ 2. Let status be the result of performing BindingInitialization
+ for lhs passing nextValue and undefined as the arguments.
+ [...]
+---*/
+
+var iterCount = 0;
+
+for (var {a, b, ...rest} of [{x: 1, y: 2, a: 5, b: 3}]) {
+ assert.sameValue(rest.a, undefined);
+ assert.sameValue(rest.b, undefined);
+
+ verifyProperty(rest, "x", {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: 1
+ });
+
+ verifyProperty(rest, "y", {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: 2
+ });
+
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/escaped-of.js b/js/src/tests/test262/language/statements/for-of/escaped-of.js
new file mode 100644
index 0000000000..6544e04603
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/escaped-of.js
@@ -0,0 +1,24 @@
+// |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-grammar-notation
+description: >
+ The `of` contextual keyword must not contain Unicode escape sequences.
+info: |
+ Terminal symbols are shown
+ in fixed width font, both in the productions of the grammars and throughout this
+ specification whenever the text directly refers to such a terminal symbol. These
+ are to appear in a script exactly as written. All terminal symbol code points
+ specified in this way are to be understood as the appropriate Unicode code points
+ from the Basic Latin range, as opposed to any similar-looking code points from
+ other Unicode ranges.
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for (var x o\u0066 []) ;
diff --git a/js/src/tests/test262/language/statements/for-of/float32array-mutate.js b/js/src/tests/test262/language/statements/for-of/float32array-mutate.js
new file mode 100644
index 0000000000..08de44b6fa
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/float32array-mutate.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4
+description: Float32Array mutation during traversal using for..of
+info: |
+ Float32Array instances should be able to be traversed using a `for..of`
+ loop, and dynamic changes to their contents should be reflected in the
+ iterated values.
+features: [TypedArray]
+---*/
+
+var iterationCount = 0;
+var array = new Float32Array([3, 2, 4, 1]);
+
+var first = 3;
+var second = 64;
+var third = 4;
+var fourth = 1;
+
+for (var x of array) {
+ assert.sameValue(x, first);
+
+ first = second;
+ second = third;
+ third = fourth;
+ fourth = null;
+
+ array[1] = 64;
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 4);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/float32array.js b/js/src/tests/test262/language/statements/for-of/float32array.js
new file mode 100644
index 0000000000..71555e9ecd
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/float32array.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4
+description: Float32Array traversal using for..of
+info: |
+ Float32Array instances should be able to be traversed using a `for..of`
+ loop.
+features: [TypedArray]
+---*/
+
+var iterationCount = 0;
+var array = new Float32Array([3, 2, 4, 1]);
+
+var first = 3;
+var second = 2;
+var third = 4;
+var fourth = 1;
+
+for (var x of array) {
+ assert.sameValue(x, first);
+
+ first = second;
+ second = third;
+ third = fourth;
+ fourth = null;
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 4);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/float64array-mutate.js b/js/src/tests/test262/language/statements/for-of/float64array-mutate.js
new file mode 100644
index 0000000000..2b88e4687d
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/float64array-mutate.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4
+description: Float64Array mutation during traversal using for..of
+info: |
+ Float64Array instances should be able to be traversed using a `for..of`
+ loop, and dynamic changes to their contents should be reflected in the
+ iterated values.
+features: [TypedArray]
+---*/
+
+var iterationCount = 0;
+var array = new Float64Array([3, 2, 4, 1]);
+
+var first = 3;
+var second = 64;
+var third = 4;
+var fourth = 1;
+
+for (var x of array) {
+ assert.sameValue(x, first);
+
+ first = second;
+ second = third;
+ third = fourth;
+ fourth = null;
+
+ array[1] = 64;
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 4);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/float64array.js b/js/src/tests/test262/language/statements/for-of/float64array.js
new file mode 100644
index 0000000000..82c4115661
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/float64array.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4
+description: Float64Array traversal using for..of
+info: |
+ Float64Array instances should be able to be traversed using a `for..of`
+ loop.
+features: [TypedArray]
+---*/
+
+var iterationCount = 0;
+var array = new Float64Array([3, 2, 4, 1]);
+
+var first = 3;
+var second = 2;
+var third = 4;
+var fourth = 1;
+
+for (var x of array) {
+ assert.sameValue(x, first);
+
+ first = second;
+ second = third;
+ third = fourth;
+ fourth = null;
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 4);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/generator-close-via-break.js b/js/src/tests/test262/language/statements/for-of/generator-close-via-break.js
new file mode 100644
index 0000000000..7548f0fccd
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/generator-close-via-break.js
@@ -0,0 +1,49 @@
+// Copyright (C) 2015 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: >
+ Generators should be closed via their `return` method when iteration is
+ interrupted via a `break` statement.
+features: [generators]
+---*/
+
+var startedCount = 0;
+var finallyCount = 0;
+var iterationCount = 0;
+function* values() {
+ startedCount += 1;
+ try {
+ yield;
+ throw new Test262Error('This code is unreachable (within `try` block)');
+ } finally {
+ finallyCount += 1;
+ }
+ throw new Test262Error('This code is unreachable (following `try` statement)');
+}
+var iterable = values();
+
+assert.sameValue(
+ startedCount, 0, 'Generator is initialized in suspended state'
+);
+
+for (var x of iterable) {
+ assert.sameValue(
+ startedCount, 1, 'Generator executes prior to first iteration'
+ );
+ assert.sameValue(
+ finallyCount, 0, 'Generator is paused during first iteration'
+ );
+ iterationCount += 1;
+ break;
+}
+
+assert.sameValue(
+ startedCount, 1, 'Generator does not restart following interruption'
+);
+assert.sameValue(iterationCount, 1, 'A single iteration occurs');
+assert.sameValue(
+ finallyCount, 1, 'Generator is closed after `break` statement'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/generator-close-via-continue.js b/js/src/tests/test262/language/statements/for-of/generator-close-via-continue.js
new file mode 100644
index 0000000000..8e6088fca7
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/generator-close-via-continue.js
@@ -0,0 +1,67 @@
+// Copyright (C) 2017 André Bargull. 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
+description: >
+ Generators should be closed via their `return` method when iteration is
+ interrupted via a `continue` statement.
+info: |
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation ( lhs, stmt, iteratorRecord, iterationKind, lhsKind, labelSet )
+ ...
+ 5. Repeat,
+ ...
+ i. Let result be the result of evaluating stmt.
+ ...
+ k. If LoopContinues(result, labelSet) is false, then
+ i. If iterationKind is enumerate, then
+ ...
+ ii. Else,
+ 1. Assert: iterationKind is iterate.
+ 2. Return ? IteratorClose(iteratorRecord, UpdateEmpty(result, V)).
+ ...
+
+features: [generators]
+---*/
+
+var startedCount = 0;
+var finallyCount = 0;
+var iterationCount = 0;
+function* values() {
+ startedCount += 1;
+ try {
+ yield;
+ throw new Test262Error('This code is unreachable (within `try` block)');
+ } finally {
+ finallyCount += 1;
+ }
+ throw new Test262Error('This code is unreachable (following `try` statement)');
+}
+var iterable = values();
+
+assert.sameValue(
+ startedCount, 0, 'Generator is initialized in suspended state'
+);
+
+L: do {
+ for (var x of iterable) {
+ assert.sameValue(
+ startedCount, 1, 'Generator executes prior to first iteration'
+ );
+ assert.sameValue(
+ finallyCount, 0, 'Generator is paused during first iteration'
+ );
+ iterationCount += 1;
+ continue L;
+ }
+} while (false);
+
+assert.sameValue(
+ startedCount, 1, 'Generator does not restart following interruption'
+);
+assert.sameValue(iterationCount, 1, 'A single iteration occurs');
+assert.sameValue(
+ finallyCount, 1, 'Generator is closed after `continue` statement'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/generator-close-via-return.js b/js/src/tests/test262/language/statements/for-of/generator-close-via-return.js
new file mode 100644
index 0000000000..93ad8963ee
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/generator-close-via-return.js
@@ -0,0 +1,51 @@
+// Copyright (C) 2015 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: >
+ Generators should be closed via their `return` method when iteration is
+ interrupted via a `return` statement.
+features: [generators]
+---*/
+
+var startedCount = 0;
+var finallyCount = 0;
+var iterationCount = 0;
+function* values() {
+ startedCount += 1;
+ try {
+ yield;
+ throw new Test262Error('This code is unreachable (within `try` block)');
+ } finally {
+ finallyCount += 1;
+ }
+ throw new Test262Error('This code is unreachable (following `try` statement)');
+}
+var iterable = values();
+
+assert.sameValue(
+ startedCount, 0, 'Generator is initialized in suspended state'
+);
+
+(function() {
+ for (var x of iterable) {
+ assert.sameValue(
+ startedCount, 1, 'Generator executes prior to first iteration'
+ );
+ assert.sameValue(
+ finallyCount, 0, 'Generator is paused during first iteration'
+ );
+ iterationCount += 1;
+ return;
+ }
+}());
+
+assert.sameValue(
+ startedCount, 1, 'Generator does not restart following interruption'
+);
+assert.sameValue(iterationCount, 1, 'A single iteration occurs');
+assert.sameValue(
+ finallyCount, 1, 'Generator is closed after `return` statement'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/generator-close-via-throw.js b/js/src/tests/test262/language/statements/for-of/generator-close-via-throw.js
new file mode 100644
index 0000000000..0b5c83cb3f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/generator-close-via-throw.js
@@ -0,0 +1,51 @@
+// Copyright (C) 2015 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: >
+ Generators should be closed via their `return` method when iteration is
+ interrupted via a `throw` statement.
+features: [generators]
+---*/
+
+var startedCount = 0;
+var finallyCount = 0;
+var iterationCount = 0;
+function* values() {
+ startedCount += 1;
+ try {
+ yield;
+ throw new Test262Error('This code is unreachable (within `try` block)');
+ } finally {
+ finallyCount += 1;
+ }
+ throw new Test262Error('This code is unreachable (following `try` statement)');
+}
+var iterable = values();
+
+assert.sameValue(
+ startedCount, 0, 'Generator is initialized in suspended state'
+);
+
+try {
+ for (var x of iterable) {
+ assert.sameValue(
+ startedCount, 1, 'Generator executes prior to first iteration'
+ );
+ assert.sameValue(
+ finallyCount, 0, 'Generator is paused during first iteration'
+ );
+ iterationCount += 1;
+ throw 0;
+ }
+} catch(err) {}
+
+assert.sameValue(
+ startedCount, 1, 'Generator does not restart following interruption'
+);
+assert.sameValue(iterationCount, 1, 'A single iteration occurs');
+assert.sameValue(
+ finallyCount, 1, 'Generator is closed after `throw` statement'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/generator-next-error.js b/js/src/tests/test262/language/statements/for-of/generator-next-error.js
new file mode 100644
index 0000000000..178b6ca22a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/generator-next-error.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2015 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 S5.g
+description: >
+ If `nextResult` is an abrupt completion as per IteratorStep (ES6 7.4.5),
+ return the completion.
+features: [generators]
+---*/
+
+var iterable = (function*() {
+ throw new Test262Error();
+}());
+var iterationCount = 0;
+
+assert.throws(Test262Error, function() {
+ for (var x of iterable) {
+ iterationCount += 1;
+ }
+});
+
+assert.sameValue(iterationCount, 0, 'The loop body is not evaluated');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/generator.js b/js/src/tests/test262/language/statements/for-of/generator.js
new file mode 100644
index 0000000000..9e9029864e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/generator.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4.13
+description: >
+ Generator function should return valid iterable objects.
+features: [generators]
+---*/
+
+function* values() {
+ yield 2;
+ yield 4;
+ yield 8;
+}
+var iterable = values();
+var expected = [2, 4, 8];
+var i = 0;
+
+for (var x of iterable) {
+ assert.sameValue(x, expected[i]);
+ i++;
+}
+
+assert.sameValue(i, 3);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/generic-iterable.js b/js/src/tests/test262/language/statements/for-of/generic-iterable.js
new file mode 100644
index 0000000000..8787060dcd
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/generic-iterable.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2013 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: >
+ Generic objects with `@@iterator` protocols should function as iterables.
+features: [Symbol.iterator]
+---*/
+
+var iterable = {};
+iterable[Symbol.iterator] = function() {
+ var j = 0;
+ return {
+ next: function() {
+ j = j + 2;
+ return { value: j, done: j === 8 };
+ }
+ }
+};
+var expected = [2, 4, 6];
+var i = 0;
+
+for (var x of iterable) {
+ assert.sameValue(x, expected[i]);
+ i++;
+}
+
+assert.sameValue(i, 3);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/head-const-bound-names-dup.js b/js/src/tests/test262/language/statements/for-of/head-const-bound-names-dup.js
new file mode 100644
index 0000000000..dac34945b9
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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] of []) {}
diff --git a/js/src/tests/test262/language/statements/for-of/head-const-bound-names-fordecl-tdz.js b/js/src/tests/test262/language/statements/for-of/head-const-bound-names-fordecl-tdz.js
new file mode 100644
index 0000000000..db87ea84d7
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/head-const-bound-names-fordecl-tdz.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.
+/*---
+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 of [x]) {}
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/head-const-bound-names-in-stmt.js b/js/src/tests/test262/language/statements/for-of/head-const-bound-names-in-stmt.js
new file mode 100644
index 0000000000..709f942812
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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 of []) {
+ var x;
+}
diff --git a/js/src/tests/test262/language/statements/for-of/head-const-bound-names-let.js b/js/src/tests/test262/language/statements/for-of/head-const-bound-names-let.js
new file mode 100644
index 0000000000..0cc7d7f69d
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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 of []) {}
diff --git a/js/src/tests/test262/language/statements/for-of/head-const-fresh-binding-per-iteration.js b/js/src/tests/test262/language/statements/for-of/head-const-fresh-binding-per-iteration.js
new file mode 100644
index 0000000000..6e71d31904
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/head-const-fresh-binding-per-iteration.js
@@ -0,0 +1,21 @@
+// 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 = 0;
+let f = [undefined, undefined, undefined];
+
+for (const x of [1, 2, 3]) {
+ s += x;
+ f[x-1] = function() { return x; }
+}
+assert.sameValue(s, 6, "The value of `s` is `6`");
+assert.sameValue(f[0](), 1, "`f[0]()` returns `1`");
+assert.sameValue(f[1](), 2, "`f[1]()` returns `2`");
+assert.sameValue(f[2](), 3, "`f[2]()` returns `3`");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/head-const-init.js b/js/src/tests/test262/language/statements/for-of/head-const-init.js
new file mode 100644
index 0000000000..add93cf2df
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/head-const-init.js
@@ -0,0 +1,18 @@
+// |reftest| error:SyntaxError
+// Copyright (C) 2019 Aleksey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-iteration-statements
+description: >
+ Initializer is not allowed in head's ForDeclaration position.
+info: |
+ IterationStatement:
+ for (ForDeclaration of AssignmentExpression) Statement
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for (const x = 1 of []) {}
diff --git a/js/src/tests/test262/language/statements/for-of/head-decl-no-expr.js b/js/src/tests/test262/language/statements/for-of/head-decl-no-expr.js
new file mode 100644
index 0000000000..0c87d9f38c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/head-decl-no-expr.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: Expression not allowed in head's AssignmentExpression position
+info: |
+ IterationStatement :
+ for ( ForDeclaration of AssignmentExpression ) Statement
+es6id: 13.7
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for (let x of [], []) {}
diff --git a/js/src/tests/test262/language/statements/for-of/head-expr-no-expr.js b/js/src/tests/test262/language/statements/for-of/head-expr-no-expr.js
new file mode 100644
index 0000000000..1eaee5c3cd
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/head-expr-no-expr.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: Expression not allowed in head's AssignmentExpression position
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+es6id: 13.7
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+var x;
+for (x of [], []) {}
diff --git a/js/src/tests/test262/language/statements/for-of/head-expr-obj-iterator-method.js b/js/src/tests/test262/language/statements/for-of/head-expr-obj-iterator-method.js
new file mode 100644
index 0000000000..f154ee03ee
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/head-expr-obj-iterator-method.js
@@ -0,0 +1,15 @@
+// Copyright (C) 2013 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 S8.b
+description: >
+ The value of the expression in a for-of statement's head must have an
+ `@@iterator` method.
+---*/
+var x;
+
+assert.throws(TypeError, function() {
+ for (x of {}) {}
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/head-expr-primitive-iterator-method.js b/js/src/tests/test262/language/statements/for-of/head-expr-primitive-iterator-method.js
new file mode 100644
index 0000000000..3326899d4d
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/head-expr-primitive-iterator-method.js
@@ -0,0 +1,19 @@
+// Copyright (C) 2013 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 S8.b
+description: >
+ The value of the expression in a for-of statement's head must have an
+ `@@iterator` method.
+---*/
+var x;
+
+assert.throws(TypeError, function() {
+ for (x of false) {}
+});
+
+assert.throws(TypeError, function() {
+ for (x of 37) {}
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/head-expr-to-obj.js b/js/src/tests/test262/language/statements/for-of/head-expr-to-obj.js
new file mode 100644
index 0000000000..c099d8514e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/head-expr-to-obj.js
@@ -0,0 +1,19 @@
+// Copyright (C) 2013 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 S8.b
+description: >
+ The value of the expression in a for-of statement's head is subject to the
+ semantics of the ToObject abstract operation.
+---*/
+var x;
+
+assert.throws(TypeError, function() {
+ for (x of null) {}
+});
+
+assert.throws(TypeError, function() {
+ for (x of undefined) {}
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/head-let-bound-names-dup.js b/js/src/tests/test262/language/statements/for-of/head-let-bound-names-dup.js
new file mode 100644
index 0000000000..6ba5438e46
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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] of []) {}
diff --git a/js/src/tests/test262/language/statements/for-of/head-let-bound-names-fordecl-tdz.js b/js/src/tests/test262/language/statements/for-of/head-let-bound-names-fordecl-tdz.js
new file mode 100644
index 0000000000..f10b0aee99
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/head-let-bound-names-fordecl-tdz.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.
+/*---
+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 of [x]) {}
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/head-let-bound-names-in-stmt.js b/js/src/tests/test262/language/statements/for-of/head-let-bound-names-in-stmt.js
new file mode 100644
index 0000000000..d369c7500a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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 of []) {
+ var x;
+}
diff --git a/js/src/tests/test262/language/statements/for-of/head-let-bound-names-let.js b/js/src/tests/test262/language/statements/for-of/head-let-bound-names-let.js
new file mode 100644
index 0000000000..a655ce474b
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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 of []) {}
diff --git a/js/src/tests/test262/language/statements/for-of/head-let-destructuring.js b/js/src/tests/test262/language/statements/for-of/head-let-destructuring.js
new file mode 100644
index 0000000000..38a486c702
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/head-let-destructuring.js
@@ -0,0 +1,30 @@
+// 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
+es6id: 13.7.5
+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] of
+ AssignmentExpression[+In, ?Yield] ) Statement[?Yield, ?Return]
+
+ for ( ForDeclaration[?Yield] of AssignmentExpression[+In, ?Yield] )
+ Statement[?Yield, ?Return]
+---*/
+
+var value;
+
+for ( let[x] of [[34]] ) {
+ value = x;
+}
+
+assert.sameValue(typeof x, 'undefined', 'binding is block-scoped');
+assert.sameValue(value, 34);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/head-let-fresh-binding-per-iteration.js b/js/src/tests/test262/language/statements/for-of/head-let-fresh-binding-per-iteration.js
new file mode 100644
index 0000000000..63fa65a902
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/head-let-fresh-binding-per-iteration.js
@@ -0,0 +1,21 @@
+// 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: >
+ let ForDeclaration: creates a fresh binding per iteration
+---*/
+
+let s = 0;
+let f = [undefined, undefined, undefined];
+
+for (let x of [1, 2, 3]) {
+ s += x;
+ f[x-1] = function() { return x; }
+}
+assert.sameValue(s, 6, "The value of `s` is `6`");
+assert.sameValue(f[0](), 1, "`f[0]()` returns `1`");
+assert.sameValue(f[1](), 2, "`f[1]()` returns `2`");
+assert.sameValue(f[2](), 3, "`f[2]()` returns `3`");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/head-let-init.js b/js/src/tests/test262/language/statements/for-of/head-let-init.js
new file mode 100644
index 0000000000..12c5474626
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/head-let-init.js
@@ -0,0 +1,18 @@
+// |reftest| error:SyntaxError
+// Copyright (C) 2019 Aleksey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-iteration-statements
+description: >
+ Initializer is not allowed in head's ForDeclaration position.
+info: |
+ IterationStatement:
+ for (ForDeclaration of AssignmentExpression) Statement
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for (let x = 1 of []) {}
diff --git a/js/src/tests/test262/language/statements/for-of/head-lhs-async-dot.js b/js/src/tests/test262/language/statements/for-of/head-lhs-async-dot.js
new file mode 100644
index 0000000000..17df347635
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/head-lhs-async-dot.js
@@ -0,0 +1,17 @@
+// Copyright (C) 2021 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: leading `async` token in for-of LHS
+info: |
+ The `async` token is allowed in the LHS if not followed by `of`
+esid: sec-for-in-and-for-of-statements
+---*/
+
+var async = { x: 0 };
+
+for (async.x of [1]) ;
+
+assert.sameValue(async.x, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/head-lhs-async-escaped.js b/js/src/tests/test262/language/statements/for-of/head-lhs-async-escaped.js
new file mode 100644
index 0000000000..1ca7a75819
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/head-lhs-async-escaped.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2021 Stuart Cook. 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: >
+ The left-hand-side of a for-of loop may be the identifier `async` written
+ with an escape sequence.
+info: |
+ ForInOfStatement[Yield, Await, Return] :
+ for ( [lookahead ∉ { let, async of }] LeftHandSideExpression[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return]
+---*/
+
+let async;
+
+for (\u0061sync of [7]);
+
+assert.sameValue(async, 7);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/head-lhs-async-invalid.js b/js/src/tests/test262/language/statements/for-of/head-lhs-async-invalid.js
new file mode 100644
index 0000000000..3d8d10bec5
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/head-lhs-async-invalid.js
@@ -0,0 +1,18 @@
+// |reftest| error:SyntaxError
+// Copyright (C) 2021 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: leading `async` token in for-of LHS
+info: |
+ The `async` token is disallowed in the LHS when followed by `of`
+esid: sec-for-in-and-for-of-statements
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+var async;
+for (async of [1]) ;
diff --git a/js/src/tests/test262/language/statements/for-of/head-lhs-async-parens.js b/js/src/tests/test262/language/statements/for-of/head-lhs-async-parens.js
new file mode 100644
index 0000000000..34eb4bd373
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/head-lhs-async-parens.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2021 Stuart Cook. 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: >
+ The left-hand-side of a for-of loop may be the identifier `async`
+ surrounded by parentheses.
+info: |
+ ForInOfStatement[Yield, Await, Return] :
+ for ( [lookahead ∉ { let, async of }] LeftHandSideExpression[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return]
+---*/
+
+let async;
+
+for ((async) of [7]);
+
+assert.sameValue(async, 7);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/head-lhs-cover-non-asnmt-trgt.js b/js/src/tests/test262/language/statements/for-of/head-lhs-cover-non-asnmt-trgt.js
new file mode 100644
index 0000000000..2806eb1eaf
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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) of []) {}
diff --git a/js/src/tests/test262/language/statements/for-of/head-lhs-cover.js b/js/src/tests/test262/language/statements/for-of/head-lhs-cover.js
new file mode 100644
index 0000000000..49858e3dc0
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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) of [23]) {
+ assert.sameValue(x, 23);
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/head-lhs-invalid-asnmt-ptrn-ary.js b/js/src/tests/test262/language/statements/for-of/head-lhs-invalid-asnmt-ptrn-ary.js
new file mode 100644
index 0000000000..830700bec8
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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)] of []) {}
diff --git a/js/src/tests/test262/language/statements/for-of/head-lhs-invalid-asnmt-ptrn-obj.js b/js/src/tests/test262/language/statements/for-of/head-lhs-invalid-asnmt-ptrn-obj.js
new file mode 100644
index 0000000000..2c212c6c8c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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() {} } of []) {}
diff --git a/js/src/tests/test262/language/statements/for-of/head-lhs-let.js b/js/src/tests/test262/language/statements/for-of/head-lhs-let.js
new file mode 100644
index 0000000000..9872264ab4
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/head-lhs-let.js
@@ -0,0 +1,26 @@
+// |reftest| error:SyntaxError
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-for-in-and-for-of-statements
+es6id: 13.7.5
+description: >
+ The `let` token is disallowed when not followed by a `[` token
+info: |
+ Syntax
+
+ IterationStatement[Yield, Return]:
+
+ for ( [lookahead ≠ let]LeftHandSideExpression[?Yield] of
+ AssignmentExpression[+In, ?Yield] ) Statement[?Yield, ?Return]
+
+ for ( ForDeclaration[?Yield] of AssignmentExpression[+In, ?Yield] )
+ Statement[?Yield, ?Return]
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for ( let of [] ) ;
diff --git a/js/src/tests/test262/language/statements/for-of/head-lhs-member.js b/js/src/tests/test262/language/statements/for-of/head-lhs-member.js
new file mode 100644
index 0000000000..5b856d14cc
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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 of [23]) {
+ assert.sameValue(x.y, 23);
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/head-lhs-non-asnmt-trgt.js b/js/src/tests/test262/language/statements/for-of/head-lhs-non-asnmt-trgt.js
new file mode 100644
index 0000000000..718bf845bc
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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 of []) {}
diff --git a/js/src/tests/test262/language/statements/for-of/head-var-bound-names-dup.js b/js/src/tests/test262/language/statements/for-of/head-var-bound-names-dup.js
new file mode 100644
index 0000000000..a7b14d9bba
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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] of [[1, 2]]) {
+ assert.sameValue(x, 2);
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/head-var-bound-names-in-stmt.js b/js/src/tests/test262/language/statements/for-of/head-var-bound-names-in-stmt.js
new file mode 100644
index 0000000000..2802adff96
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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 of [99]) {
+ var x;
+
+ assert.sameValue(x, 99);
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/head-var-bound-names-let.js b/js/src/tests/test262/language/statements/for-of/head-var-bound-names-let.js
new file mode 100644
index 0000000000..b81e65bb9d
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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 of [23]) {
+ assert.sameValue(let, 23);
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/head-var-init.js b/js/src/tests/test262/language/statements/for-of/head-var-init.js
new file mode 100644
index 0000000000..a135479d83
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/head-var-init.js
@@ -0,0 +1,18 @@
+// |reftest| error:SyntaxError
+// Copyright (C) 2019 Aleksey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-iteration-statements
+description: >
+ Initializer is not allowed in head's ForBinding position.
+info: |
+ IterationStatement:
+ for (var ForBinding of AssignmentExpression) Statement
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for (var x = 1 of []) {}
diff --git a/js/src/tests/test262/language/statements/for-of/head-var-no-expr.js b/js/src/tests/test262/language/statements/for-of/head-var-no-expr.js
new file mode 100644
index 0000000000..995fd4e45e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/head-var-no-expr.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: Expression not allowed in head's AssignmentExpression position
+info: |
+ IterationStatement :
+ for ( var ForBinding of AssignmentExpression ) Statement
+es6id: 13.7
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for (var x of [], []) {}
diff --git a/js/src/tests/test262/language/statements/for-of/int16array-mutate.js b/js/src/tests/test262/language/statements/for-of/int16array-mutate.js
new file mode 100644
index 0000000000..fe86a96857
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/int16array-mutate.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4
+description: Int16Array mutation during traversal using for..of
+info: |
+ Int16Array instances should be able to be traversed using a `for..of` loop,
+ and dynamic changes to their contents should be reflected in the iterated
+ values.
+features: [TypedArray]
+---*/
+
+var iterationCount = 0;
+var array = new Int16Array([3, 2, 4, 1]);
+
+var first = 3;
+var second = 64;
+var third = 4;
+var fourth = 1;
+
+for (var x of array) {
+ assert.sameValue(x, first);
+
+ first = second;
+ second = third;
+ third = fourth;
+ fourth = null;
+
+ array[1] = 64;
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 4);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/int16array.js b/js/src/tests/test262/language/statements/for-of/int16array.js
new file mode 100644
index 0000000000..413dff5488
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/int16array.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4
+description: >
+ Int16Array instances should be able to be traversed using a `for..of` loop.
+features: [TypedArray]
+---*/
+
+var iterationCount = 0;
+var array = new Int16Array([3, 2, 4, 1]);
+
+var first = 3;
+var second = 2;
+var third = 4;
+var fourth = 1;
+
+for (var x of array) {
+ assert.sameValue(x, first);
+
+ first = second;
+ second = third;
+ third = fourth;
+ fourth = null;
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 4);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/int32array-mutate.js b/js/src/tests/test262/language/statements/for-of/int32array-mutate.js
new file mode 100644
index 0000000000..f19f70e27a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/int32array-mutate.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4
+description: Int32Array mutation during traversal using for..of
+info: |
+ Int32Array instances should be able to be traversed using a `for..of` loop,
+ and dynamic changes to their contents should be reflected in the iterated
+ values.
+features: [TypedArray]
+---*/
+
+var iterationCount = 0;
+var array = new Int32Array([3, 2, 4, 1]);
+
+var first = 3;
+var second = 64;
+var third = 4;
+var fourth = 1;
+
+for (var x of array) {
+ assert.sameValue(x, first);
+
+ first = second;
+ second = third;
+ third = fourth;
+ fourth = null;
+
+ array[1] = 64;
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 4);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/int32array.js b/js/src/tests/test262/language/statements/for-of/int32array.js
new file mode 100644
index 0000000000..3bbbd033e5
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/int32array.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4
+description: >
+ Int32Array instances should be able to be traversed using a `for..of` loop.
+features: [TypedArray]
+---*/
+
+var iterationCount = 0;
+var array = new Int32Array([3, 2, 4, 1]);
+
+var first = 3;
+var second = 2;
+var third = 4;
+var fourth = 1;
+
+for (var x of array) {
+ assert.sameValue(x, first);
+
+ first = second;
+ second = third;
+ third = fourth;
+ fourth = null;
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 4);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/int8array-mutate.js b/js/src/tests/test262/language/statements/for-of/int8array-mutate.js
new file mode 100644
index 0000000000..96a79760f0
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/int8array-mutate.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4
+description: Int8Array mutation during traversal using for..of
+info: |
+ Int8Array instances should be able to be traversed using a `for..of` loop,
+ and dynamic changes to their contents should be reflected in the iterated
+ values.
+features: [TypedArray]
+---*/
+
+var iterationCount = 0;
+var array = new Int8Array([3, 2, 4, 1]);
+
+var first = 3;
+var second = 64;
+var third = 4;
+var fourth = 1;
+
+for (var x of array) {
+ assert.sameValue(x, first);
+
+ first = second;
+ second = third;
+ third = fourth;
+ fourth = null;
+
+ array[1] = 64;
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 4);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/int8array.js b/js/src/tests/test262/language/statements/for-of/int8array.js
new file mode 100644
index 0000000000..a4351d6b0e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/int8array.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4
+description: >
+ Int8Array instances should be able to be traversed using a `for..of` loop.
+features: [TypedArray]
+---*/
+
+var iterationCount = 0;
+var array = new Int8Array([3, 2, 4, 1]);
+
+var first = 3;
+var second = 2;
+var third = 4;
+var fourth = 1;
+
+for (var x of array) {
+ assert.sameValue(x, first);
+
+ first = second;
+ second = third;
+ third = fourth;
+ fourth = null;
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 4);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/iterator-as-proxy.js b/js/src/tests/test262/language/statements/for-of/iterator-as-proxy.js
new file mode 100644
index 0000000000..89bab3e8ab
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/iterator-as-proxy.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4.13
+description: >
+ Iterators that are implemented as proxies should behave identically to
+ non-proxy versions.
+features: [Proxy, Symbol.iterator]
+---*/
+
+var iterable = {};
+var nextResult = { value: 23, done: false };
+var lastResult = { value: null, done: true };
+var i;
+
+var iterator = {
+ next: function() {
+ var result = nextResult;
+ nextResult = lastResult;
+ return result;
+ }
+};
+var proxiedIterator = new Proxy(iterator, {
+ get: function(target, name) {
+ return target[name];
+ }
+});
+iterable[Symbol.iterator] = function() { return proxiedIterator; };
+
+i = 0;
+for (var x of iterable) {
+ assert.sameValue(x, 23);
+ i++;
+}
+
+assert.sameValue(i, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/iterator-close-non-object.js b/js/src/tests/test262/language/statements/for-of/iterator-close-non-object.js
new file mode 100644
index 0000000000..6d1f4a8ad9
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/iterator-close-non-object.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2015 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: >
+ If an iterator's `return` method returns a non-Object value, a TypeError
+ should be thrown.
+features: [Symbol.iterator]
+---*/
+
+var iterable = {};
+var iterationCount = 0;
+
+iterable[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { done: false, value: null };
+ },
+ return: function() {
+ return 0;
+ }
+ };
+};
+
+assert.throws(TypeError, function() {
+ for (var x of iterable) {
+ iterationCount += 1;
+ break;
+ }
+});
+
+assert.sameValue(iterationCount, 1, 'The loop body is evaluated');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/iterator-close-non-throw-get-method-abrupt.js b/js/src/tests/test262/language/statements/for-of/iterator-close-non-throw-get-method-abrupt.js
new file mode 100644
index 0000000000..4d5be580ad
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/iterator-close-non-throw-get-method-abrupt.js
@@ -0,0 +1,49 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-iteratorclose
+description: >
+ If retrieving an iterator's `return` method generates an error while
+ closing the iterator with non-throw completion, the error should be
+ forwarded to the runtime.
+info: |
+ IteratorClose ( iteratorRecord, completion )
+
+ [...]
+ 4. Let innerResult be GetMethod(iterator, "return").
+ 5. If innerResult.[[Type]] is normal,
+ [...]
+ 6. If completion.[[Type]] is throw, return Completion(completion).
+ 7. If innerResult.[[Type]] is throw, return Completion(innerResult).
+
+ GetMethod ( V, P )
+
+ [...]
+ 2. Let func be ? GetV(V, P).
+features: [Symbol.iterator]
+---*/
+
+var iterable = {};
+var iterationCount = 0;
+
+iterable[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { done: false, value: null };
+ },
+ get return() {
+ throw new Test262Error();
+ }
+ };
+};
+
+assert.throws(Test262Error, function() {
+ for (var x of iterable) {
+ iterationCount += 1;
+ break;
+ }
+});
+
+assert.sameValue(iterationCount, 1, 'The loop body is evaluated');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/iterator-close-non-throw-get-method-is-null.js b/js/src/tests/test262/language/statements/for-of/iterator-close-non-throw-get-method-is-null.js
new file mode 100644
index 0000000000..509d32f420
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/iterator-close-non-throw-get-method-is-null.js
@@ -0,0 +1,49 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-iteratorclose
+description: >
+ If iterator's "return" method is `null`,
+ received non-throw completion is forwarded to the runtime.
+info: |
+ IteratorClose ( iteratorRecord, completion )
+
+ [...]
+ 4. Let innerResult be GetMethod(iterator, "return").
+ 5. If innerResult.[[Type]] is normal,
+ a. Let return be innerResult.[[Value]].
+ b. If return is undefined, return Completion(completion).
+
+ GetMethod ( V, P )
+
+ [...]
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+features: [Symbol.iterator]
+---*/
+
+var iterationCount = 0;
+var returnGets = 0;
+
+var iterable = {};
+iterable[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return {value: 1, done: false};
+ },
+ get return() {
+ returnGets += 1;
+ return null;
+ },
+ };
+};
+
+for (var _ of iterable) {
+ iterationCount += 1;
+ break;
+}
+
+assert.sameValue(iterationCount, 1);
+assert.sameValue(returnGets, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/iterator-close-non-throw-get-method-non-callable.js b/js/src/tests/test262/language/statements/for-of/iterator-close-non-throw-get-method-non-callable.js
new file mode 100644
index 0000000000..f7715d3135
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/iterator-close-non-throw-get-method-non-callable.js
@@ -0,0 +1,49 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-iteratorclose
+description: >
+ If retrieving an iterator's `return` method generates an error while
+ closing the iterator with non-throw completion, the error should be
+ forwarded to the runtime.
+info: |
+ IteratorClose ( iteratorRecord, completion )
+
+ [...]
+ 4. Let innerResult be GetMethod(iterator, "return").
+ 5. If innerResult.[[Type]] is normal,
+ [...]
+ 6. If completion.[[Type]] is throw, return Completion(completion).
+ 7. If innerResult.[[Type]] is throw, return Completion(innerResult).
+
+ GetMethod ( V, P )
+
+ [...]
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+features: [Symbol.iterator]
+---*/
+
+var iterable = {};
+var iterationCount = 0;
+
+iterable[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { done: false, value: null };
+ },
+ return: 1,
+ };
+};
+
+assert.throws(TypeError, function() {
+ for (var x of iterable) {
+ iterationCount += 1;
+ break;
+ }
+});
+
+assert.sameValue(iterationCount, 1, 'The loop body is evaluated');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/iterator-close-throw-get-method-abrupt.js b/js/src/tests/test262/language/statements/for-of/iterator-close-throw-get-method-abrupt.js
new file mode 100644
index 0000000000..926a58efc6
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/iterator-close-throw-get-method-abrupt.js
@@ -0,0 +1,48 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-iteratorclose
+description: >
+ If retrieving an iterator's `return` method generates an error while
+ closing the iterator with throw completion, this error should be suppressed.
+info: |
+ IteratorClose ( iteratorRecord, completion )
+
+ [...]
+ 4. Let innerResult be GetMethod(iterator, "return").
+ 5. If innerResult.[[Type]] is normal,
+ [...]
+ 6. If completion.[[Type]] is throw, return Completion(completion).
+ 7. If innerResult.[[Type]] is throw, return Completion(innerResult).
+
+ GetMethod ( V, P )
+
+ [...]
+ 2. Let func be ? GetV(V, P).
+features: [Symbol.iterator]
+---*/
+
+var iterable = {};
+var iterationCount = 0;
+
+iterable[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { done: false, value: null };
+ },
+ get return() {
+ throw { name: 'inner error' };
+ },
+ };
+};
+
+assert.throws(Test262Error, function() {
+ for (var x of iterable) {
+ iterationCount += 1;
+ throw new Test262Error('should not be overriden');
+ }
+});
+
+assert.sameValue(iterationCount, 1, 'The loop body is evaluated');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/iterator-close-throw-get-method-non-callable.js b/js/src/tests/test262/language/statements/for-of/iterator-close-throw-get-method-non-callable.js
new file mode 100644
index 0000000000..ffb7be7ea1
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/iterator-close-throw-get-method-non-callable.js
@@ -0,0 +1,48 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-iteratorclose
+description: >
+ If retrieving an iterator's `return` method generates an error while
+ closing the iterator with throw completion, this error should be suppressed.
+info: |
+ IteratorClose ( iteratorRecord, completion )
+
+ [...]
+ 4. Let innerResult be GetMethod(iterator, "return").
+ 5. If innerResult.[[Type]] is normal,
+ [...]
+ 6. If completion.[[Type]] is throw, return Completion(completion).
+ 7. If innerResult.[[Type]] is throw, return Completion(innerResult).
+
+ GetMethod ( V, P )
+
+ [...]
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+features: [Symbol.iterator]
+---*/
+
+var iterable = {};
+var iterationCount = 0;
+
+iterable[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { done: false, value: null };
+ },
+ return: 'str',
+ };
+};
+
+assert.throws(Test262Error, function() {
+ for (var x of iterable) {
+ iterationCount += 1;
+ throw new Test262Error('should not be overriden');
+ }
+});
+
+assert.sameValue(iterationCount, 1, 'The loop body is evaluated');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/iterator-close-via-break.js b/js/src/tests/test262/language/statements/for-of/iterator-close-via-break.js
new file mode 100644
index 0000000000..c324bffe55
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/iterator-close-via-break.js
@@ -0,0 +1,48 @@
+// Copyright (C) 2015 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: >
+ Iterators should be closed via their `return` method when iteration is
+ interrupted via a `break` statement.
+features: [Symbol.iterator]
+---*/
+
+var startedCount = 0;
+var returnCount = 0;
+var iterationCount = 0;
+var iterable = {};
+
+iterable[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ startedCount += 1;
+ return { done: false, value: null };
+ },
+ return: function() {
+ returnCount += 1;
+ return {};
+ }
+ };
+};
+
+for (var x of iterable) {
+ assert.sameValue(
+ startedCount, 1, 'Value is retrieved'
+ );
+ assert.sameValue(
+ returnCount, 0, 'Iterator is not closed'
+ );
+ iterationCount += 1;
+ break;
+}
+
+assert.sameValue(
+ startedCount, 1, 'Iterator does not restart following interruption'
+);
+assert.sameValue(iterationCount, 1, 'A single iteration occurs');
+assert.sameValue(
+ returnCount, 1, 'Iterator is closed after `break` statement'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/iterator-close-via-continue.js b/js/src/tests/test262/language/statements/for-of/iterator-close-via-continue.js
new file mode 100644
index 0000000000..f2ffaedcd0
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/iterator-close-via-continue.js
@@ -0,0 +1,66 @@
+// Copyright (C) 2017 André Bargull. 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
+description: >
+ Iterators should be closed via their `return` method when iteration is
+ interrupted via a `continue` statement.
+info: |
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation ( lhs, stmt, iteratorRecord, iterationKind, lhsKind, labelSet )
+ ...
+ 5. Repeat,
+ ...
+ i. Let result be the result of evaluating stmt.
+ ...
+ k. If LoopContinues(result, labelSet) is false, then
+ i. If iterationKind is enumerate, then
+ ...
+ ii. Else,
+ 1. Assert: iterationKind is iterate.
+ 2. Return ? IteratorClose(iteratorRecord, UpdateEmpty(result, V)).
+ ...
+
+features: [Symbol.iterator]
+---*/
+
+var startedCount = 0;
+var returnCount = 0;
+var iterationCount = 0;
+var iterable = {};
+
+iterable[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ startedCount += 1;
+ return { done: false, value: null };
+ },
+ return: function() {
+ returnCount += 1;
+ return {};
+ }
+ };
+};
+
+L: do {
+ for (var x of iterable) {
+ assert.sameValue(
+ startedCount, 1, 'Value is retrieved'
+ );
+ assert.sameValue(
+ returnCount, 0, 'Iterator is not closed'
+ );
+ iterationCount += 1;
+ continue L;
+ }
+} while (false);
+
+assert.sameValue(
+ startedCount, 1, 'Iterator does not restart following interruption'
+);
+assert.sameValue(iterationCount, 1, 'A single iteration occurs');
+assert.sameValue(
+ returnCount, 1, 'Iterator is closed after `continue` statement'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/iterator-close-via-return.js b/js/src/tests/test262/language/statements/for-of/iterator-close-via-return.js
new file mode 100644
index 0000000000..b82fbfa4a9
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/iterator-close-via-return.js
@@ -0,0 +1,50 @@
+// Copyright (C) 2015 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: >
+ Iterators should be closed via their `return` method when iteration is
+ interrupted via a `return` statement.
+features: [Symbol.iterator]
+---*/
+
+var startedCount = 0;
+var returnCount = 0;
+var iterationCount = 0;
+var iterable = {};
+
+iterable[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ startedCount += 1;
+ return { done: false, value: null };
+ },
+ return: function() {
+ returnCount += 1;
+ return {};
+ }
+ };
+};
+
+(function() {
+ for (var x of iterable) {
+ assert.sameValue(
+ startedCount, 1, 'Value is retrieved'
+ );
+ assert.sameValue(
+ returnCount, 0, 'Iterator is not closed'
+ );
+ iterationCount += 1;
+ return;
+ }
+}());
+
+assert.sameValue(
+ startedCount, 1, 'Iterator does not restart following interruption'
+);
+assert.sameValue(iterationCount, 1, 'A single iteration occurs');
+assert.sameValue(
+ returnCount, 1, 'Iterator is closed after `return` statement'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/iterator-close-via-throw.js b/js/src/tests/test262/language/statements/for-of/iterator-close-via-throw.js
new file mode 100644
index 0000000000..675d73b01e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/iterator-close-via-throw.js
@@ -0,0 +1,50 @@
+// Copyright (C) 2015 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: >
+ Iterators should be closed via their `return` method when iteration is
+ interrupted via a `throw` statement.
+features: [Symbol.iterator]
+---*/
+
+var startedCount = 0;
+var returnCount = 0;
+var iterationCount = 0;
+var iterable = {};
+
+iterable[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ startedCount += 1;
+ return { done: false, value: null };
+ },
+ return: function() {
+ returnCount += 1;
+ return {};
+ }
+ };
+};
+
+try {
+ for (var x of iterable) {
+ assert.sameValue(
+ startedCount, 1, 'Value is retrieved'
+ );
+ assert.sameValue(
+ returnCount, 0, 'Iterator is not closed'
+ );
+ iterationCount += 1;
+ throw 0;
+ }
+} catch (err) {}
+
+assert.sameValue(
+ startedCount, 1, 'Iterator does not restart following interruption'
+);
+assert.sameValue(iterationCount, 1, 'A single iteration occurs');
+assert.sameValue(
+ returnCount, 1, 'Iterator is closed after `throw` statement'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/iterator-next-error.js b/js/src/tests/test262/language/statements/for-of/iterator-next-error.js
new file mode 100644
index 0000000000..1df2e8ef29
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/iterator-next-error.js
@@ -0,0 +1,40 @@
+// Copyright (C) 2015 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 S5.d
+description: >
+ If `nextResult` is an abrupt completion as per IteratorStep (ES6 7.4.5),
+ return the completion.
+info: |
+ [...]
+ 5. Repeat
+ a. Let nextResult be ? IteratorStep(iterator).
+features: [Symbol.iterator]
+---*/
+
+var iterable = {};
+var iterationCount = 0;
+var returnCount = 0;
+
+iterable[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ throw new Test262Error();
+ },
+ return: function() {
+ returnCount += 1;
+ return {};
+ }
+ };
+};
+
+assert.throws(Test262Error, function() {
+ for (var x of iterable) {
+ iterationCount += 1;
+ }
+});
+
+assert.sameValue(iterationCount, 0, 'The loop body is not evaluated');
+assert.sameValue(returnCount, 0, 'Iterator is not closed.');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/iterator-next-reference.js b/js/src/tests/test262/language/statements/for-of/iterator-next-reference.js
new file mode 100644
index 0000000000..29b9cc4080
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/iterator-next-reference.js
@@ -0,0 +1,43 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-getiterator
+description: >
+ The iterator's `next` method should be accessed only once with each
+ iteration as per the `GetIterator` abstract operation (7.4.1).
+features: [Symbol.iterator, for-of]
+---*/
+
+var iterable = {};
+var iterator = {};
+var iterationCount = 0;
+var loadNextCount = 0;
+
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+function next() {
+ if (iterationCount) return { done: true };
+ return { value: 45, done: false };
+}
+Object.defineProperty(iterator, 'next', {
+ get() { loadNextCount++; return next; },
+ configurable: true
+});
+
+for (var x of iterable) {
+ assert.sameValue(x, 45);
+
+ Object.defineProperty(iterator, 'next', {
+ get: function() {
+ throw new Test262Error(
+ 'Should not access the `next` method after the iteration prologue.');
+ }
+ });
+ iterationCount++;
+}
+assert.sameValue(iterationCount, 1);
+assert.sameValue(loadNextCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/iterator-next-result-done-attr.js b/js/src/tests/test262/language/statements/for-of/iterator-next-result-done-attr.js
new file mode 100644
index 0000000000..415e5997e2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/iterator-next-result-done-attr.js
@@ -0,0 +1,132 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 7.4.3
+description: >
+ The `done` value of iteration result objects should be interpreted as
+ incomplete as per `ToBoolean` (7.1.2).
+features: [Symbol.iterator]
+---*/
+
+var iterable = {};
+var i, firstIterResult;
+
+iterable[Symbol.iterator] = function() {
+ var finalIterResult = { value: null, done: true };
+ var nextIterResult = firstIterResult;
+
+ return {
+ next: function() {
+ var iterResult = nextIterResult;
+
+ nextIterResult = finalIterResult;
+
+ return iterResult;
+ }
+ };
+};
+
+firstIterResult = { value: null, done: undefined };
+i = 0;
+for (var x of iterable) {
+ i++;
+}
+assert.sameValue(i, 1);
+
+firstIterResult = { value: null };
+i = 0;
+for (var x of iterable) {
+ i++;
+}
+assert.sameValue(i, 1);
+
+firstIterResult = { value: null, done: null };
+i = 0;
+for (var x of iterable) {
+ i++;
+}
+assert.sameValue(i, 1);
+
+firstIterResult = { value: null, done: false };
+i = 0;
+for (var x of iterable) {
+ i++;
+}
+assert.sameValue(i, 1);
+
+firstIterResult = { value: null, done: true };
+i = 0;
+for (var x of iterable) {
+ i++;
+}
+assert.sameValue(i, 0);
+
+firstIterResult = { value: null, done: 1 };
+i = 0;
+for (var x of iterable) {
+ i++;
+}
+assert.sameValue(i, 0);
+
+firstIterResult = { value: null, done: 0 };
+i = 0;
+for (var x of iterable) {
+ i++;
+}
+assert.sameValue(i, 1);
+
+firstIterResult = { value: null, done: -0 };
+i = 0;
+for (var x of iterable) {
+ i++;
+}
+assert.sameValue(i, 1);
+
+firstIterResult = { value: null, done: NaN };
+i = 0;
+for (var x of iterable) {
+ i++;
+}
+assert.sameValue(i, 1);
+
+firstIterResult = { value: null, done: '' };
+i = 0;
+for (var x of iterable) {
+ i++;
+}
+assert.sameValue(i, 1);
+
+firstIterResult = { value: null, done: '0' };
+i = 0;
+for (var x of iterable) {
+ i++;
+}
+assert.sameValue(i, 0);
+
+firstIterResult = { value: null, done: Symbol() };
+i = 0;
+for (var x of iterable) {
+ i++;
+}
+assert.sameValue(i, 0);
+
+firstIterResult = { value: null, done: {} };
+i = 0;
+for (var x of iterable) {
+ i++;
+}
+assert.sameValue(i, 0);
+
+firstIterResult = { value: null };
+Object.defineProperty(firstIterResult, 'done', {
+ get: function() {
+ return true;
+ }
+});
+i = 0;
+for (var x of iterable) {
+ i++;
+}
+assert.sameValue(i, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/iterator-next-result-type.js b/js/src/tests/test262/language/statements/for-of/iterator-next-result-type.js
new file mode 100644
index 0000000000..46bc36d784
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/iterator-next-result-type.js
@@ -0,0 +1,108 @@
+// Copyright (C) 2013 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 S5.c
+description: >
+ If Type(result) is not Object, throw a TypeError exception as per
+ `IteratorNext` (7.4.2 S4)
+features: [Symbol.iterator]
+---*/
+
+var iterable = {};
+var firstIterResult;
+
+iterable[Symbol.iterator] = function() {
+ var finalIterResult = { value: null, done: true };
+ var nextIterResult = firstIterResult;
+
+ return {
+ next: function() {
+ var iterResult = nextIterResult;
+
+ nextIterResult = finalIterResult;
+
+ return iterResult;
+ }
+ };
+};
+
+firstIterResult = true;
+assert.throws(TypeError, function() {
+ for (var x of iterable) {}
+});
+
+firstIterResult = false;
+assert.throws(TypeError, function() {
+ for (var x of iterable) {}
+});
+
+firstIterResult = 'string';
+assert.throws(TypeError, function() {
+ for (var x of iterable) {}
+});
+
+firstIterResult = undefined;
+assert.throws(TypeError, function() {
+ for (var x of iterable) {}
+});
+
+firstIterResult = null;
+assert.throws(TypeError, function() {
+ for (var x of iterable) {}
+});
+
+firstIterResult = 4;
+assert.throws(TypeError, function() {
+ for (var x of iterable) {}
+});
+
+firstIterResult = NaN;
+assert.throws(TypeError, function() {
+ for (var x of iterable) {}
+});
+
+firstIterResult = Symbol('s');
+assert.throws(TypeError, function() {
+ for (var x of iterable) {}
+});
+
+firstIterResult = /regexp/;
+for (var x of iterable) {}
+
+firstIterResult = {};
+for (var x of iterable) {}
+
+firstIterResult = new Proxy({}, {
+ get: function(receiver, name) {
+ if (name === 'done') {
+ return true;
+ }
+ if (name === 'value') {
+ return null;
+ }
+ throw new Test262Error('This code is unreachable.');
+ }
+});
+for (var x of iterable) {
+ throw new Test262Error('This code is unreachable.');
+}
+
+firstIterResult = new Proxy({}, {
+ get: function(receiver, name) {
+ if (name === 'done') {
+ return false;
+ }
+ if (name === 'value') {
+ return 23;
+ }
+ throw new Test262Error('This code is unreachable.');
+ }
+});
+var i = 0;
+for (var x of iterable) {
+ assert.sameValue(x, 23);
+ i++;
+}
+assert.sameValue(i, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/iterator-next-result-value-attr-error.js b/js/src/tests/test262/language/statements/for-of/iterator-next-result-value-attr-error.js
new file mode 100644
index 0000000000..1f0592f4a7
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/iterator-next-result-value-attr-error.js
@@ -0,0 +1,47 @@
+// Copyright (C) 2015 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 S5.g
+description: >
+ If `nextValue` is an abrupt completion as per IteratorValue (ES6 7.4.4),
+ return the completion.
+info: |
+ [...]
+ 5. Repeat
+ a. Let nextResult be ? IteratorStep(iterator).
+ b. If nextResult is false, return NormalCompletion(V).
+ c. Let nextValue be ? IteratorValue(nextResult).
+features: [Symbol.iterator]
+---*/
+
+var iterable = {};
+var iterationCount = 0;
+var returnCount = 0;
+
+iterable[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return {
+ done: false,
+ get value() {
+ throw new Test262Error();
+ }
+ };
+ },
+ return: function() {
+ returnCount += 1;
+ return {};
+ }
+ };
+};
+
+assert.throws(Test262Error, function() {
+ for (var x of iterable) {
+ iterationCount += 1;
+ }
+});
+
+assert.sameValue(iterationCount, 0, 'The loop body is not evaluated');
+assert.sameValue(returnCount, 0, 'Iterator is not closed.');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/iterator-next-result-value-attr.js b/js/src/tests/test262/language/statements/for-of/iterator-next-result-value-attr.js
new file mode 100644
index 0000000000..27076c53de
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/iterator-next-result-value-attr.js
@@ -0,0 +1,50 @@
+// Copyright (C) 2013 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 S5.f
+description: >
+ The `value` of iteration result objects should be retrieved using the Get
+ abstract operation.
+features: [Symbol.iterator]
+---*/
+
+var iterable = {};
+var i, firstIterResult;
+
+iterable[Symbol.iterator] = function() {
+ var finalIterResult = { value: null, done: true };
+ var nextIterResult = firstIterResult;
+
+ return {
+ next: function() {
+ var iterResult = nextIterResult;
+
+ nextIterResult = finalIterResult;
+
+ return iterResult;
+ }
+ };
+};
+
+firstIterResult = { value: 45, done: false };
+i = 0;
+for (var x of iterable) {
+ assert.sameValue(x, 45);
+ i++;
+}
+assert.sameValue(i, 1);
+
+firstIterResult = { done: false };
+Object.defineProperty(firstIterResult, 'value', {
+ get: function() {
+ return 23;
+ }
+});
+i = 0;
+for (var x of iterable) {
+ assert.sameValue(x, 23);
+ i++;
+}
+assert.sameValue(i, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/labelled-fn-stmt-const.js b/js/src/tests/test262/language/statements/for-of/labelled-fn-stmt-const.js
new file mode 100644
index 0000000000..fa964e8d6f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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 of []) label1: label2: function f() {}
diff --git a/js/src/tests/test262/language/statements/for-of/labelled-fn-stmt-let.js b/js/src/tests/test262/language/statements/for-of/labelled-fn-stmt-let.js
new file mode 100644
index 0000000000..6ae9837cae
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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 of []) label1: label2: function f() {}
diff --git a/js/src/tests/test262/language/statements/for-of/labelled-fn-stmt-lhs.js b/js/src/tests/test262/language/statements/for-of/labelled-fn-stmt-lhs.js
new file mode 100644
index 0000000000..efdb27cd32
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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 of []) label1: label2: function f() {}
diff --git a/js/src/tests/test262/language/statements/for-of/labelled-fn-stmt-var.js b/js/src/tests/test262/language/statements/for-of/labelled-fn-stmt-var.js
new file mode 100644
index 0000000000..086cc38999
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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 of []) label1: label2: function f() {}
diff --git a/js/src/tests/test262/language/statements/for-of/let-array-with-newline.js b/js/src/tests/test262/language/statements/for-of/let-array-with-newline.js
new file mode 100644
index 0000000000..179fdad77f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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 of []) let
+[a] = 0;
diff --git a/js/src/tests/test262/language/statements/for-of/let-block-with-newline.js b/js/src/tests/test262/language/statements/for-of/let-block-with-newline.js
new file mode 100644
index 0000000000..a5ca01e125
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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 of []) let // ASI
+{}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/let-identifier-with-newline.js b/js/src/tests/test262/language/statements/for-of/let-identifier-with-newline.js
new file mode 100644
index 0000000000..e383835c93
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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 of []) let // ASI
+x = 1;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/map-contract-expand.js b/js/src/tests/test262/language/statements/for-of/map-contract-expand.js
new file mode 100644
index 0000000000..c9cc3ed190
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/map-contract-expand.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Map entry removal and re-insertion during traversal using for..of
+info: |
+ Entries removed from a Map instance during traversal should be visited if
+ they are re-inserted prior to iterator exhaustion.
+es6id: 13.6.4
+features: [Map]
+---*/
+
+var map = new Map();
+var iterationCount = 0;
+
+var first = [0, 'a'];
+var second = [1, 'b'];
+
+map.set(0, 'a');
+map.set(1, 'b');
+
+for (var x of map) {
+ assert.sameValue(x[0], first[0]);
+ assert.sameValue(x[1], first[1]);
+
+ first = second;
+ second = null;
+
+ if (first !== null) {
+ map.delete(1);
+ map.set(1, 'b');
+ }
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 2);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/map-contract.js b/js/src/tests/test262/language/statements/for-of/map-contract.js
new file mode 100644
index 0000000000..e068d4f51f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/map-contract.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Entries removed from a Map instance during traversal should not be visited.
+es6id: 13.6.4
+features: [Map]
+---*/
+
+var map = new Map();
+var iterationCount = 0;
+
+map.set(0, 'a');
+map.set(1, 'b');
+
+for (var x of map) {
+ assert.sameValue(x[0], 0);
+ assert.sameValue(x[1], 'a');
+ map.delete(1);
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/map-expand-contract.js b/js/src/tests/test262/language/statements/for-of/map-expand-contract.js
new file mode 100644
index 0000000000..cd1c2ed6dc
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/map-expand-contract.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Map entry insertion during traversal using for..of
+info: |
+ New entries inserted into a Map instance during traversal should not be
+ visited if they are removed prior to visitation.
+es6id: 13.6.4
+features: [Map]
+---*/
+
+var map = new Map();
+var iterationCount = 0;
+
+map.set(0, 'a');
+
+for (var x of map) {
+ assert.sameValue(x[0], 0);
+ assert.sameValue(x[1], 'a');
+
+ map.set(1, 'b');
+ map.delete(1);
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/map-expand.js b/js/src/tests/test262/language/statements/for-of/map-expand.js
new file mode 100644
index 0000000000..044dd0cf2d
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/map-expand.js
@@ -0,0 +1,35 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Map entry insertion during traversal using for..of
+info: |
+ New entries inserted into a Map instance during traversal should be
+ visited.
+es6id: 13.6.4
+features: [Map]
+---*/
+
+var map = new Map();
+var iterationCount = 0;
+
+var first = [0, 'a'];
+var second = [1, 'b'];
+
+map.set(0, 'a');
+
+for (var x of map) {
+ assert.sameValue(x[0], first[0]);
+ assert.sameValue(x[1], first[1]);
+
+ first = second;
+ second = null;
+
+ map.set(1, 'b');
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 2);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/map.js b/js/src/tests/test262/language/statements/for-of/map.js
new file mode 100644
index 0000000000..c7a936192c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/map.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Map traversal using for..of
+info: |
+ Map instances should be able to be traversed using a `for...of` loop.
+es6id: 13.6.4
+features: [Map]
+---*/
+
+var map = new Map();
+var obj = {};
+var iterationCount = 0;
+
+var first = [0, 'a'];
+var second = [true, false];
+var third = [null, undefined];
+var fourth = [NaN, obj];
+
+map.set(0, 'a');
+map.set(true, false);
+map.set(null, undefined);
+map.set(NaN, obj);
+
+for (var x of map) {
+ assert.sameValue(x[0], first[0]);
+ assert.sameValue(x[1], first[1]);
+ first = second;
+ second = third;
+ third = fourth;
+ fourth = null;
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 4);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/nested.js b/js/src/tests/test262/language/statements/for-of/nested.js
new file mode 100644
index 0000000000..54fefe3876
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/nested.js
@@ -0,0 +1,40 @@
+// Copyright (C) 2013 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: >
+ Nested statements should operate independently.
+features: [generators]
+---*/
+
+function* values() {
+ yield 3;
+ yield 7;
+}
+
+var outerIterable, expectedOuter, i, innerIterable, expectedInner, j;
+
+outerIterable = values();
+expectedOuter = 3;
+i = 0;
+
+for (var x of outerIterable) {
+ assert.sameValue(x, expectedOuter);
+ expectedOuter = 7;
+ i++;
+
+ innerIterable = values();
+ expectedInner = 3;
+ j = 0;
+ for (var y of innerIterable) {
+ assert.sameValue(y, expectedInner);
+ expectedInner = 7;
+ j++;
+ }
+
+ assert.sameValue(j, 2);
+}
+
+assert.sameValue(i, 2);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/return-from-catch.js b/js/src/tests/test262/language/statements/for-of/return-from-catch.js
new file mode 100644
index 0000000000..ac33a21d23
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/return-from-catch.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2015 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: >
+ Control flow during body evaluation should honor `return` statements within
+ the `catch` block of `try` statements.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ throw new Test262Error('This code is unreachable (following `yield` statement).');
+}
+var iterator = values();
+var i = 0;
+
+var result = (function() {
+ for (var x of iterator) {
+ try {
+ throw new Error();
+ } catch(err) {
+ i++;
+ return 34;
+
+ throw new Test262Error('This code is unreachable (following `return` statement).');
+ }
+
+ throw new Test262Error('This code is unreachable (following `try` statement).');
+ }
+
+ throw new Test262Error('This code is unreachable (following `for..in` statement).');
+})();
+
+assert.sameValue(result, 34);
+assert.sameValue(i, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/return-from-finally.js b/js/src/tests/test262/language/statements/for-of/return-from-finally.js
new file mode 100644
index 0000000000..24d4895616
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/return-from-finally.js
@@ -0,0 +1,37 @@
+// Copyright (C) 2015 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: >
+ Control flow during body evaluation should honor `return` statements within
+ the `finally` block of `try` statements.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ throw new Test262Error('This code is unreachable (following `yield` statement).');
+}
+var iterator = values();
+var i = 0;
+
+var result = (function() {
+ for (var x of iterator) {
+ try {
+ } finally {
+ i++;
+ return 34;
+
+ throw new Test262Error('This code is unreachable (following `return` statement).');
+ }
+
+ throw new Test262Error('This code is unreachable (following `try` statement).');
+ }
+
+ throw new Test262Error('This code is unreachable (following `for..in` statement).');
+})();
+
+assert.sameValue(result, 34);
+assert.sameValue(i, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/return-from-try.js b/js/src/tests/test262/language/statements/for-of/return-from-try.js
new file mode 100644
index 0000000000..1804b1a6f5
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/return-from-try.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2015 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: >
+ Control flow during body evaluation should honor `return` statements within
+ `try` blocks.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ throw new Test262Error('This code is unreachable (following `yield` statement).');
+}
+var iterator = values();
+var i = 0;
+
+var result = (function() {
+ for (var x of iterator) {
+ try {
+ i++;
+ return 34;
+
+ throw new Test262Error('This code is unreachable (following `return` statement).');
+ } catch(err) {
+ throw new Test262Error('This code is unreachable (within `catch` block).');
+ }
+
+ throw new Test262Error('This code is unreachable (following `try` statement).');
+ }
+
+ throw new Test262Error('This code is unreachable (following `for..in` statement).');
+})();
+
+assert.sameValue(result, 34);
+assert.sameValue(i, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/return.js b/js/src/tests/test262/language/statements/for-of/return.js
new file mode 100644
index 0000000000..79657ef84c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/return.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4.13
+description: >
+ Control flow during body evaluation should honor `return` statements.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ throw new Test262Error('This code is unreachable (following `yield` statement).');
+}
+var iterator = values();
+var i = 0;
+
+var result = (function() {
+ for (var x of iterator) {
+ i++;
+ return 34;
+
+ throw new Test262Error('This code is unreachable (following `return` statement).');
+ }
+
+ throw new Test262Error('This code is unreachable (following `for..of` statement).');
+})();
+
+assert.sameValue(result, 34);
+assert.sameValue(i, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/scope-body-lex-boundary.js b/js/src/tests/test262/language/statements/for-of/scope-body-lex-boundary.js
new file mode 100644
index 0000000000..7377a24939
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/scope-body-lex-boundary.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 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 of ['first', 'second'])
+ if (!probeFirst)
+ probeFirst = function() { return x; };
+ else
+ probeSecond = function() { return x; };
+
+assert.sameValue(probeFirst(), 'first');
+assert.sameValue(probeSecond(), 'second');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/scope-body-lex-close.js b/js/src/tests/test262/language/statements/for-of/scope-body-lex-close.js
new file mode 100644
index 0000000000..96689c07c8
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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; }]
+ of
+ [['inside']]
+ )
+ probeBody = function() { return x; };
+
+assert.sameValue(probeDecl(), 'inside', 'reference from ForDeclaration');
+assert.sameValue(probeBody(), 'inside', 'reference from statement body');
+assert.sameValue(x, 'outside');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/scope-body-lex-open.js b/js/src/tests/test262/language/statements/for-of/scope-body-lex-open.js
new file mode 100644
index 0000000000..39459e016a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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; }]
+ of
+ [['inside', probeExpr = function() { typeof x; }]]
+ )
+ probeBody = function() { return x; };
+
+assert.sameValue(probeBefore(), 'outside');
+assert.throws(ReferenceError, probeExpr);
+assert.sameValue(probeDecl(), 'inside', 'reference from ForDeclaration');
+assert.sameValue(probeBody(), 'inside', 'reference from statement body');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/scope-body-var-none.js b/js/src/tests/test262/language/statements/for-of/scope-body-var-none.js
new file mode 100644
index 0000000000..dddb7964a3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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; }]
+ of
+ [[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 ForDelaration');
+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-of/scope-head-lex-close.js b/js/src/tests/test262/language/statements/for-of/scope-head-lex-close.js
new file mode 100644
index 0000000000..d84859e4c0
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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; }]
+ of
+ (probeExpr = function() { typeof x; }, [['inside']])
+ )
+ probeBody = function() { return x; };
+
+assert.throws(ReferenceError, probeExpr);
+assert.sameValue(probeDecl(), 'inside', 'reference from ForDeclaration');
+assert.sameValue(probeBody(), 'inside', 'reference from statement body');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/scope-head-lex-open.js b/js/src/tests/test262/language/statements/for-of/scope-head-lex-open.js
new file mode 100644
index 0000000000..36789d239a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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 of (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-of/scope-head-var-none.js b/js/src/tests/test262/language/statements/for-of/scope-head-var-none.js
new file mode 100644
index 0000000000..18268d0959
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/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; }]
+ of
+ [[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-of/set-contract-expand.js b/js/src/tests/test262/language/statements/for-of/set-contract-expand.js
new file mode 100644
index 0000000000..4a397815e9
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/set-contract-expand.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Set entry removal and re-insertion during traversal using for..of
+info: |
+ Entries removed from a Set instance during traversal should be visited if
+ they are re-inserted prior to iterator exhaustion.
+es6id: 13.6.4
+features: [Set]
+---*/
+
+var set = new Set();
+var iterationCount = 0;
+
+var first = 0;
+var second = 1;
+
+set.add(0);
+set.add(1);
+
+for (var x of set) {
+ assert.sameValue(x, first);
+
+ first = second;
+ second = null;
+
+ if (first !== null) {
+ set.delete(1);
+ set.add(1);
+ }
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 2);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/set-contract.js b/js/src/tests/test262/language/statements/for-of/set-contract.js
new file mode 100644
index 0000000000..7b952027bb
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/set-contract.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Entries removed from a Set instance during traversal should not be visited.
+es6id: 13.6.4
+features: [Set]
+---*/
+
+var set = new Set();
+var iterationCount = 0;
+
+set.add(0);
+set.add(1);
+
+for (var x of set) {
+ assert.sameValue(x, 0);
+ set.delete(1);
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/set-expand-contract.js b/js/src/tests/test262/language/statements/for-of/set-expand-contract.js
new file mode 100644
index 0000000000..29264dde6f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/set-expand-contract.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Set entry insertion and removal during traversal using for..of
+info: |
+ New entries inserted into a Set instance during traversal should not be
+ visited if they are removed prior to visitation.
+es6id: 13.6.4
+features: [Set]
+---*/
+
+var set = new Set();
+var iterationCount = 0;
+
+set.add(0);
+
+for (var x of set) {
+ assert.sameValue(x, 0);
+
+ set.add(1);
+ set.delete(1);
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/set-expand.js b/js/src/tests/test262/language/statements/for-of/set-expand.js
new file mode 100644
index 0000000000..56aca39e95
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/set-expand.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Set entry insertaion during traversal using for..of
+info: |
+ New entries inserted into a Set instance during traversal should be
+ visited.
+es6id: 13.6.4
+features: [Set]
+---*/
+
+var set = new Set();
+var iterationCount = 0;
+
+var first = 0;
+var second = 1;
+
+set.add(0);
+
+for (var x of set) {
+ assert.sameValue(x, first);
+
+ first = second;
+ second = null;
+
+ set.add(1);
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 2);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/set.js b/js/src/tests/test262/language/statements/for-of/set.js
new file mode 100644
index 0000000000..ad11782018
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/set.js
@@ -0,0 +1,48 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Set instances should be able to be traversed using a `for...of` loop.
+es6id: 13.6.4
+features: [Set]
+---*/
+
+var set = new Set();
+var obj = {};
+var iterationCount = 0;
+
+var first = 0;
+var second = 'a';
+var third = true;
+var fourth = false;
+var fifth = null;
+var sixth = undefined;
+var seventh = NaN;
+var eight = obj;
+
+set.add(0);
+set.add('a');
+set.add(true);
+set.add(false);
+set.add(null);
+set.add(undefined);
+set.add(NaN);
+set.add(obj);
+
+for (var x of set) {
+ assert.sameValue(x, first);
+ first = second;
+ second = third;
+ third = fourth;
+ fourth = fifth;
+ fifth = sixth;
+ sixth = seventh;
+ seventh = eight;
+ eight = null;
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 8);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/shell.js b/js/src/tests/test262/language/statements/for-of/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/shell.js
diff --git a/js/src/tests/test262/language/statements/for-of/string-astral-truncated.js b/js/src/tests/test262/language/statements/for-of/string-astral-truncated.js
new file mode 100644
index 0000000000..97f580b52a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/string-astral-truncated.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: String traversal using for..of (incomplete surrogate pairs)
+info: |
+ String literals should be able to be traversed using a `for...of` loop. The
+ loop body should execute once for each incomplete surrogate pair.
+es6id: 13.6.4
+---*/
+
+var string = 'a\ud801b\ud801';
+var first = 'a';
+var second = '\ud801';
+var third = 'b';
+var fourth = '\ud801';
+
+var iterationCount = 0;
+
+for (var value of string) {
+ assert.sameValue(value, first);
+ first = second;
+ second = third;
+ third = fourth;
+ fourth = null;
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 4);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/string-astral.js b/js/src/tests/test262/language/statements/for-of/string-astral.js
new file mode 100644
index 0000000000..f203124fb7
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/string-astral.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: String traversal using for..of (astral symbols)
+info: |
+ String literals should be able to be traversed using a `for...of` loop. The
+ loop body should execute once for each astral symbol.
+es6id: 13.6.4
+---*/
+
+var string = 'a\ud801\udc28b\ud801\udc28';
+var first = 'a';
+var second = '𐐨';
+var third = 'b';
+var fourth = '𐐨';
+
+var iterationCount = 0;
+
+for (var value of string) {
+ assert.sameValue(value, first);
+ first = second;
+ second = third;
+ third = fourth;
+ fourth = null;
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 4);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/string-bmp.js b/js/src/tests/test262/language/statements/for-of/string-bmp.js
new file mode 100644
index 0000000000..1f5d4334b6
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/string-bmp.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: String traversal using for..of
+info: |
+ String literals should be able to be traversed using a `for...of` loop. The
+ loop body should execute once for every BMP character.
+es6id: 13.6.4
+---*/
+
+var string = 'abc';
+var first = 'a';
+var second = 'b';
+var third = 'c';
+
+var iterationCount = 0;
+
+for (var value of string) {
+ assert.sameValue(value, first);
+ first = second;
+ second = third;
+ third = null;
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 3);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/throw-from-catch.js b/js/src/tests/test262/language/statements/for-of/throw-from-catch.js
new file mode 100644
index 0000000000..554f35185a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/throw-from-catch.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 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: >
+ Control flow during body evaluation should honor `throw` statements within
+ the `catch` block of `try` statements.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ throw new Test262Error('This code is unreachable (following `yield` statement).');
+}
+var CustomError = function() {};
+var iterator = values();
+var i = 0;
+var error = new CustomError();
+
+assert.throws(CustomError, function() {
+ for (var x of iterator) {
+ try {
+ throw new Error();
+ } catch (err) {
+ i++;
+ throw error;
+
+ throw new Test262Error('This code is unreachable (following `throw` statement).');
+ }
+
+ throw new Test262Error('This code is unreachable (following `try` statement).');
+ }
+
+ throw new Test262Error('This code is unreachable (following `for..in` statement).');
+});
+
+assert.sameValue(i, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/throw-from-finally.js b/js/src/tests/test262/language/statements/for-of/throw-from-finally.js
new file mode 100644
index 0000000000..860f6919e9
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/throw-from-finally.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2015 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: >
+ Control flow during body evaluation should honor `throw` statements within
+ the `finally` block of `try` statements.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ throw new Test262Error('This code is unreachable (following `yield` statement).');
+}
+var CustomError = function() {};
+var iterator = values();
+var i = 0;
+var error = new CustomError();
+
+assert.throws(CustomError, function() {
+ for (var x of iterator) {
+ try {
+ } finally {
+ i++;
+ throw error;
+
+ throw new Test262Error('This code is unreachable (following `throw` statement).');
+ }
+
+ throw new Test262Error('This code is unreachable (following `try` statement).');
+ }
+
+ throw new Test262Error('This code is unreachable (following `for..in` statement).');
+});
+
+assert.sameValue(i, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/throw.js b/js/src/tests/test262/language/statements/for-of/throw.js
new file mode 100644
index 0000000000..65998a1e27
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/throw.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 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: >
+ Control flow during body evaluation should honor `throw` statements.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ throw new Test262Error('This code is unreachable (following `yield` statement).');
+}
+var CustomError = function() {};
+var iterator = values();
+var i = 0;
+var error = new CustomError();
+
+assert.throws(CustomError, function() {
+ for (var x of iterator) {
+ i++;
+ throw error;
+
+ throw new Test262Error('This code is unreachable (following `throw` statement).');
+ }
+
+ throw new Test262Error('This code is unreachable (following `for..in` statement).');
+});
+
+assert.sameValue(i, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/uint16array-mutate.js b/js/src/tests/test262/language/statements/for-of/uint16array-mutate.js
new file mode 100644
index 0000000000..1ad2c43635
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/uint16array-mutate.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4
+description: Uint16Array mutation during traversal using for..of
+info: |
+ Uint16Array instances should be able to be traversed using a `for..of`
+ loop, and dynamic changes to their contents should be reflected in the
+ iterated values.
+features: [TypedArray]
+---*/
+
+var iterationCount = 0;
+var array = new Uint16Array([3, 2, 4, 1]);
+
+var first = 3;
+var second = 64;
+var third = 4;
+var fourth = 1;
+
+for (var x of array) {
+ assert.sameValue(x, first);
+
+ first = second;
+ second = third;
+ third = fourth;
+ fourth = null;
+
+ array[1] = 64;
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 4);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/uint16array.js b/js/src/tests/test262/language/statements/for-of/uint16array.js
new file mode 100644
index 0000000000..1bd129216f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/uint16array.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4
+description: Uint16Array traversal using for..of
+info: |
+ Uint16Array instances should be able to be traversed using a `for..of`
+ loop.
+features: [TypedArray]
+---*/
+
+var iterationCount = 0;
+var array = new Uint16Array([3, 2, 4, 1]);
+
+var first = 3;
+var second = 2;
+var third = 4;
+var fourth = 1;
+
+for (var x of array) {
+ assert.sameValue(x, first);
+
+ first = second;
+ second = third;
+ third = fourth;
+ fourth = null;
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 4);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/uint32array-mutate.js b/js/src/tests/test262/language/statements/for-of/uint32array-mutate.js
new file mode 100644
index 0000000000..d1330b8124
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/uint32array-mutate.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4
+description: Uint32Array mutation during traversal using for..of
+info: |
+ Uint32Array instances should be able to be traversed using a `for..of`
+ loop, and dynamic changes to their contents should be reflected in the
+ iterated values.
+features: [TypedArray]
+---*/
+
+var iterationCount = 0;
+var array = new Uint32Array([3, 2, 4, 1]);
+
+var first = 3;
+var second = 64;
+var third = 4;
+var fourth = 1;
+
+for (var x of array) {
+ assert.sameValue(x, first);
+
+ first = second;
+ second = third;
+ third = fourth;
+ fourth = null;
+
+ array[1] = 64;
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 4);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/uint32array.js b/js/src/tests/test262/language/statements/for-of/uint32array.js
new file mode 100644
index 0000000000..0f39d498a0
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/uint32array.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4
+description: Uint32Array traversal using for..of
+info: |
+ Uint32Array instances should be able to be traversed using a `for..of`
+ loop.
+features: [TypedArray]
+---*/
+
+var iterationCount = 0;
+var array = new Uint32Array([3, 2, 4, 1]);
+
+var first = 3;
+var second = 2;
+var third = 4;
+var fourth = 1;
+
+for (var x of array) {
+ assert.sameValue(x, first);
+
+ first = second;
+ second = third;
+ third = fourth;
+ fourth = null;
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 4);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/uint8array-mutate.js b/js/src/tests/test262/language/statements/for-of/uint8array-mutate.js
new file mode 100644
index 0000000000..6bd78fcd7c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/uint8array-mutate.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4
+description: Uint8Array mutation during traversal using for..of
+info: |
+ Uint8Array instances should be able to be traversed using a `for..of` loop,
+ and dynamic changes to their contents should be reflected in the iterated
+ values.
+features: [TypedArray]
+---*/
+
+var iterationCount = 0;
+var array = new Uint8Array([3, 2, 4, 1]);
+
+var first = 3;
+var second = 64;
+var third = 4;
+var fourth = 1;
+
+for (var x of array) {
+ assert.sameValue(x, first);
+
+ first = second;
+ second = third;
+ third = fourth;
+ fourth = null;
+
+ array[1] = 64;
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 4);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/uint8array.js b/js/src/tests/test262/language/statements/for-of/uint8array.js
new file mode 100644
index 0000000000..df5e234b48
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/uint8array.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4
+description: >
+ Uint8Array instances should be able to be traversed using a `for..of` loop.
+features: [TypedArray]
+---*/
+
+var iterationCount = 0;
+var array = new Uint8Array([3, 2, 4, 1]);
+
+var first = 3;
+var second = 2;
+var third = 4;
+var fourth = 1;
+
+for (var x of array) {
+ assert.sameValue(x, first);
+
+ first = second;
+ second = third;
+ third = fourth;
+ fourth = null;
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 4);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/uint8clampedarray-mutate.js b/js/src/tests/test262/language/statements/for-of/uint8clampedarray-mutate.js
new file mode 100644
index 0000000000..63623ac6f3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/uint8clampedarray-mutate.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4
+description: Uint8ClampedArray mutation during traversal using for..of
+info: |
+ Uint8ClampedArray instances should be able to be traversed using a
+ `for..of` loop, and dynamic changes to their contents should be reflected
+ in the iterated values.
+features: [TypedArray]
+---*/
+
+var iterationCount = 0;
+var array = new Uint8ClampedArray([3, 2, 4, 1]);
+
+var first = 3;
+var second = 64;
+var third = 4;
+var fourth = 1;
+
+for (var x of array) {
+ assert.sameValue(x, first);
+
+ first = second;
+ second = third;
+ third = fourth;
+ fourth = null;
+
+ array[1] = 64;
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 4);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/uint8clampedarray.js b/js/src/tests/test262/language/statements/for-of/uint8clampedarray.js
new file mode 100644
index 0000000000..62feb76911
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/uint8clampedarray.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4
+description: >
+ Uint8ClampedArray instances should be able to be traversed using a
+ `for..of` loop.
+features: [TypedArray]
+---*/
+
+var iterationCount = 0;
+var array = new Uint8ClampedArray([3, 2, 4, 1]);
+
+var first = 3;
+var second = 2;
+var third = 4;
+var fourth = 1;
+
+for (var x of array) {
+ assert.sameValue(x, first);
+
+ first = second;
+ second = third;
+ third = fourth;
+ fourth = null;
+
+ iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 4);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/yield-from-catch.js b/js/src/tests/test262/language/statements/for-of/yield-from-catch.js
new file mode 100644
index 0000000000..c5d18a33ce
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/yield-from-catch.js
@@ -0,0 +1,54 @@
+// Copyright (C) 2015 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: >
+ Control flow during body evaluation should honor `yield` statements within
+ the `catch` block of `try` statements.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ yield 1;
+}
+var dataIterator = values();
+var controlIterator = (function*() {
+ for (var x of dataIterator) {
+ try {
+ throw new Error();
+ throw new Test262Error('This code is unreachable.');
+ } catch (err) {
+ i++;
+ yield;
+ j++;
+ }
+ k++;
+ }
+
+ l++;
+})();
+var i = 0;
+var j = 0;
+var k = 0;
+var l = 0;
+
+controlIterator.next();
+assert.sameValue(i, 1, 'First iteration: pre-yield');
+assert.sameValue(j, 0, 'First iteration: post-yield');
+assert.sameValue(k, 0, 'First iteration: post-try');
+assert.sameValue(l, 0, 'First iteration: post-for-of');
+
+controlIterator.next();
+assert.sameValue(i, 2, 'Second iteration: pre-yield');
+assert.sameValue(j, 1, 'Second iteration: post-yield');
+assert.sameValue(k, 1, 'Second iteration: post-try');
+assert.sameValue(l, 0, 'Second iteration: post-for-of');
+
+controlIterator.next();
+assert.sameValue(i, 2, 'Third iteration: pre-yield');
+assert.sameValue(j, 2, 'Third iteration: post-yield');
+assert.sameValue(k, 2, 'Third iteration: post-try');
+assert.sameValue(l, 1, 'Third iteration: post-for-of');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/yield-from-finally.js b/js/src/tests/test262/language/statements/for-of/yield-from-finally.js
new file mode 100644
index 0000000000..f569b64420
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/yield-from-finally.js
@@ -0,0 +1,52 @@
+// Copyright (C) 2015 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: >
+ Control flow during body evaluation should honor `yield` statements within
+ the `finally` block of `try` statements.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ yield 1;
+}
+var dataIterator = values();
+var controlIterator = (function*() {
+ for (var x of dataIterator) {
+ try {
+ } finally {
+ i++;
+ yield;
+ j++;
+ }
+ k++;
+ }
+
+ l++;
+})();
+var i = 0;
+var j = 0;
+var k = 0;
+var l = 0;
+
+controlIterator.next();
+assert.sameValue(i, 1, 'First iteration: pre-yield');
+assert.sameValue(j, 0, 'First iteration: post-yield');
+assert.sameValue(k, 0, 'First iteration: post-try');
+assert.sameValue(l, 0, 'First iteration: post-for-of');
+
+controlIterator.next();
+assert.sameValue(i, 2, 'Second iteration: pre-yield');
+assert.sameValue(j, 1, 'Second iteration: post-yield');
+assert.sameValue(k, 1, 'Second iteration: post-try');
+assert.sameValue(l, 0, 'Second iteration: post-for-of');
+
+controlIterator.next();
+assert.sameValue(i, 2, 'Third iteration: pre-yield');
+assert.sameValue(j, 2, 'Third iteration: post-yield');
+assert.sameValue(k, 2, 'Third iteration: post-try');
+assert.sameValue(l, 1, 'Third iteration: post-for-of');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/yield-from-try.js b/js/src/tests/test262/language/statements/for-of/yield-from-try.js
new file mode 100644
index 0000000000..068491f968
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/yield-from-try.js
@@ -0,0 +1,51 @@
+// Copyright (C) 2015 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: >
+ Control flow during body evaluation should honor `yield` statements within
+ `try` blocks.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ yield 1;
+}
+var dataIterator = values();
+var controlIterator = (function*() {
+ for (var x of dataIterator) {
+ try {
+ i++;
+ yield;
+ j++;
+ } catch (err) {}
+ k++;
+ }
+
+ l++;
+})();
+var i = 0;
+var j = 0;
+var k = 0;
+var l = 0;
+
+controlIterator.next();
+assert.sameValue(i, 1, 'First iteration: pre-yield');
+assert.sameValue(j, 0, 'First iteration: post-yield');
+assert.sameValue(k, 0, 'First iteration: post-try');
+assert.sameValue(l, 0, 'First iteration: post-for-of');
+
+controlIterator.next();
+assert.sameValue(i, 2, 'Second iteration: pre-yield');
+assert.sameValue(j, 1, 'Second iteration: post-yield');
+assert.sameValue(k, 1, 'Second iteration: post-try');
+assert.sameValue(l, 0, 'Second iteration: post-for-of');
+
+controlIterator.next();
+assert.sameValue(i, 2, 'Third iteration: pre-yield');
+assert.sameValue(j, 2, 'Third iteration: post-yield');
+assert.sameValue(k, 2, 'Third iteration: post-try');
+assert.sameValue(l, 1, 'Third iteration: post-for-of');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/yield-star-from-catch.js b/js/src/tests/test262/language/statements/for-of/yield-star-from-catch.js
new file mode 100644
index 0000000000..d1232b52ea
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/yield-star-from-catch.js
@@ -0,0 +1,66 @@
+// Copyright (C) 2015 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: >
+ Control flow during body evaluation should honor `yield *` statements
+ within the `catch` block of `try` statements.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ yield 1;
+}
+var dataIterator = values();
+var controlIterator = (function*() {
+ for (var x of dataIterator) {
+ try {
+ throw new Error();
+ throw new Test262Error('This code is unreachable.');
+ } catch (err) {
+ i++;
+ yield * values();
+ j++;
+ }
+ k++;
+ }
+
+ l++;
+})();
+var i = 0;
+var j = 0;
+var k = 0;
+var l = 0;
+
+controlIterator.next();
+assert.sameValue(i, 1, 'First iteration: pre-yield');
+assert.sameValue(j, 0, 'First iteration: post-yield');
+assert.sameValue(k, 0, 'First iteration: post-try');
+assert.sameValue(l, 0, 'First iteration: post-for-of');
+
+controlIterator.next();
+assert.sameValue(i, 1, 'Second iteration: pre-yield');
+assert.sameValue(j, 0, 'Second iteration: post-yield');
+assert.sameValue(k, 0, 'Second iteration: post-try');
+assert.sameValue(l, 0, 'Second iteration: post-for-of');
+
+controlIterator.next();
+assert.sameValue(i, 2, 'Third iteration: pre-yield');
+assert.sameValue(j, 1, 'Third iteration: post-yield');
+assert.sameValue(k, 1, 'Third iteration: post-try');
+assert.sameValue(l, 0, 'Third iteration: post-for-of');
+
+controlIterator.next();
+assert.sameValue(i, 2, 'Fourth iteration: pre-yield');
+assert.sameValue(j, 1, 'Fourth iteration: post-yield');
+assert.sameValue(k, 1, 'Fourth iteration: post-try');
+assert.sameValue(l, 0, 'Fourth iteration: post-for-of');
+
+controlIterator.next();
+assert.sameValue(i, 2, 'Fifth iteration: pre-yield');
+assert.sameValue(j, 2, 'Fifth iteration: post-yield');
+assert.sameValue(k, 2, 'Fifth iteration: post-try');
+assert.sameValue(l, 1, 'Fifth iteration: post-for-of');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/yield-star-from-finally.js b/js/src/tests/test262/language/statements/for-of/yield-star-from-finally.js
new file mode 100644
index 0000000000..b11ba7c3d1
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/yield-star-from-finally.js
@@ -0,0 +1,64 @@
+// Copyright (C) 2015 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: >
+ Control flow during body evaluation should honor `yield *` statements
+ within the `finally` block of `try` statements.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ yield 1;
+}
+var dataIterator = values();
+var controlIterator = (function*() {
+ for (var x of dataIterator) {
+ try {
+ } finally {
+ i++;
+ yield * values();
+ j++;
+ }
+ k++;
+ }
+
+ l++;
+})();
+var i = 0;
+var j = 0;
+var k = 0;
+var l = 0;
+
+controlIterator.next();
+assert.sameValue(i, 1, 'First iteration: pre-yield');
+assert.sameValue(j, 0, 'First iteration: post-yield');
+assert.sameValue(k, 0, 'First iteration: post-try');
+assert.sameValue(l, 0, 'First iteration: post-for-of');
+
+controlIterator.next();
+assert.sameValue(i, 1, 'Second iteration: pre-yield');
+assert.sameValue(j, 0, 'Second iteration: post-yield');
+assert.sameValue(k, 0, 'Second iteration: post-try');
+assert.sameValue(l, 0, 'Second iteration: post-for-of');
+
+controlIterator.next();
+assert.sameValue(i, 2, 'Third iteration: pre-yield');
+assert.sameValue(j, 1, 'Third iteration: post-yield');
+assert.sameValue(k, 1, 'Third iteration: post-try');
+assert.sameValue(l, 0, 'Third iteration: post-for-of');
+
+controlIterator.next();
+assert.sameValue(i, 2, 'Fourth iteration: pre-yield');
+assert.sameValue(j, 1, 'Fourth iteration: post-yield');
+assert.sameValue(k, 1, 'Fourth iteration: post-try');
+assert.sameValue(l, 0, 'Fourth iteration: post-for-of');
+
+controlIterator.next();
+assert.sameValue(i, 2, 'Fifth iteration: pre-yield');
+assert.sameValue(j, 2, 'Fifth iteration: post-yield');
+assert.sameValue(k, 2, 'Fifth iteration: post-try');
+assert.sameValue(l, 1, 'Fifth iteration: post-for-of');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/yield-star-from-try.js b/js/src/tests/test262/language/statements/for-of/yield-star-from-try.js
new file mode 100644
index 0000000000..ba838353d4
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/yield-star-from-try.js
@@ -0,0 +1,63 @@
+// Copyright (C) 2015 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: >
+ Control flow during body evaluation should honor `yield *` statements
+ within `try` blocks.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ yield 1;
+}
+var dataIterator = values();
+var controlIterator = (function*() {
+ for (var x of dataIterator) {
+ try {
+ i++;
+ yield * values();
+ j++;
+ } catch (err) {}
+ k++;
+ }
+
+ l++;
+})();
+var i = 0;
+var j = 0;
+var k = 0;
+var l = 0;
+
+controlIterator.next();
+assert.sameValue(i, 1, 'First iteration: pre-yield');
+assert.sameValue(j, 0, 'First iteration: post-yield');
+assert.sameValue(k, 0, 'First iteration: post-try');
+assert.sameValue(l, 0, 'First iteration: post-for-of');
+
+controlIterator.next();
+assert.sameValue(i, 1, 'Second iteration: pre-yield');
+assert.sameValue(j, 0, 'Second iteration: post-yield');
+assert.sameValue(k, 0, 'Second iteration: post-try');
+assert.sameValue(l, 0, 'Second iteration: post-for-of');
+
+controlIterator.next();
+assert.sameValue(i, 2, 'Third iteration: pre-yield');
+assert.sameValue(j, 1, 'Third iteration: post-yield');
+assert.sameValue(k, 1, 'Third iteration: post-try');
+assert.sameValue(l, 0, 'Third iteration: post-for-of');
+
+controlIterator.next();
+assert.sameValue(i, 2, 'Fourth iteration: pre-yield');
+assert.sameValue(j, 1, 'Fourth iteration: post-yield');
+assert.sameValue(k, 1, 'Fourth iteration: post-try');
+assert.sameValue(l, 0, 'Fourth iteration: post-for-of');
+
+controlIterator.next();
+assert.sameValue(i, 2, 'Fifth iteration: pre-yield');
+assert.sameValue(j, 2, 'Fifth iteration: post-yield');
+assert.sameValue(k, 2, 'Fifth iteration: post-try');
+assert.sameValue(l, 1, 'Fifth iteration: post-for-of');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/yield-star.js b/js/src/tests/test262/language/statements/for-of/yield-star.js
new file mode 100644
index 0000000000..699788a190
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/yield-star.js
@@ -0,0 +1,53 @@
+// Copyright (C) 2015 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: >
+ Control flow during body evaluation should honor `yield *` statements.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ yield 1;
+}
+var dataIterator = values();
+var controlIterator = (function*() {
+ for (var x of dataIterator) {
+ i++;
+ yield * values();
+ j++;
+ }
+
+ k++;
+})();
+var i = 0;
+var j = 0;
+var k = 0;
+
+controlIterator.next();
+assert.sameValue(i, 1, 'First iteration: pre-yield');
+assert.sameValue(j, 0, 'First iteration: post-yield');
+assert.sameValue(k, 0, 'First iteration: post-for-of');
+
+controlIterator.next();
+assert.sameValue(i, 1, 'Second iteration: pre-yield');
+assert.sameValue(j, 0, 'Second iteration: post-yield');
+assert.sameValue(k, 0, 'Second iteration: post-for-of');
+
+controlIterator.next();
+assert.sameValue(i, 2, 'Third iteration: pre-yield');
+assert.sameValue(j, 1, 'Third iteration: post-yield');
+assert.sameValue(k, 0, 'Third iteration: post-for-of');
+
+controlIterator.next();
+assert.sameValue(i, 2, 'Fourth iteration: pre-yield');
+assert.sameValue(j, 1, 'Fourth iteration: post-yield');
+assert.sameValue(k, 0, 'Fourth iteration: post-for-of');
+
+controlIterator.next();
+assert.sameValue(i, 2, 'Fifth iteration: pre-yield');
+assert.sameValue(j, 2, 'Fifth iteration: post-yield');
+assert.sameValue(k, 1, 'Fifth iteration: post-for-of');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-of/yield.js b/js/src/tests/test262/language/statements/for-of/yield.js
new file mode 100644
index 0000000000..fab8e89393
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-of/yield.js
@@ -0,0 +1,43 @@
+// Copyright (C) 2015 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: >
+ Control flow during body evaluation should honor `yield` statements.
+features: [generators]
+---*/
+
+function* values() {
+ yield 1;
+ yield 1;
+}
+var dataIterator = values();
+var controlIterator = (function*() {
+ for (var x of dataIterator) {
+ i++;
+ yield;
+ j++;
+ }
+
+ k++;
+})();
+var i = 0;
+var j = 0;
+var k = 0;
+
+controlIterator.next();
+assert.sameValue(i, 1, 'First iteration: pre-yield');
+assert.sameValue(j, 0, 'First iteration: post-yield');
+assert.sameValue(k, 0, 'First iteration: post-for-of');
+
+controlIterator.next();
+assert.sameValue(i, 2, 'Second iteration: pre-yield');
+assert.sameValue(j, 1, 'Second iteration: post-yield');
+assert.sameValue(k, 0, 'Second iteration: post-for-of');
+
+controlIterator.next();
+assert.sameValue(i, 2, 'Third iteration: pre-yield');
+assert.sameValue(j, 2, 'Third iteration: post-yield');
+assert.sameValue(k, 1, 'Third iteration: post-for-of');
+
+reportCompare(0, 0);