summaryrefslogtreecommitdiff
path: root/src/dstr-assignment
diff options
context:
space:
mode:
authorMike Pennisi <mike@mikepennisi.com>2016-05-20 18:58:23 -0400
committerMike Pennisi <mike@mikepennisi.com>2016-05-25 13:47:06 -0400
commitc24a206511841e14f156b929005b9e5597c05965 (patch)
tree64f62d6936fe2f18158ee6fc3bccfe8bb77bc656 /src/dstr-assignment
parent56b988883e3e1819cdc98b21c125be4c80f2bc24 (diff)
downloadqtdeclarative-testsuites-c24a206511841e14f156b929005b9e5597c05965.tar.gz
Re-format destructuring assignment tests
Utilize the test generation tool to increase coverage of destructuring assignment semantics. Previously, only destructuring assignment in the AssignmentExpression position was tested. With this change applied, the same tests will assert expected behavior for destructuring assignment in `for..of` statements, as well. A limited number of tests are applied to the `for..in` statement as well, but due to the iteration protocol observed by that statement, many destructuring tests are not relevant, and others cannot be automatically generated from this format.
Diffstat (limited to 'src/dstr-assignment')
-rw-r--r--src/dstr-assignment/array-elem-init-assignment.case23
-rw-r--r--src/dstr-assignment/array-elem-init-evaluation.case20
-rw-r--r--src/dstr-assignment/array-elem-init-fn-name-arrow.case32
-rw-r--r--src/dstr-assignment/array-elem-init-fn-name-class.case35
-rw-r--r--src/dstr-assignment/array-elem-init-fn-name-cover.case35
-rw-r--r--src/dstr-assignment/array-elem-init-fn-name-fn.case35
-rw-r--r--src/dstr-assignment/array-elem-init-fn-name-gen.case35
-rw-r--r--src/dstr-assignment/array-elem-init-in.case18
-rw-r--r--src/dstr-assignment/array-elem-init-let.case21
-rw-r--r--src/dstr-assignment/array-elem-init-order.case21
-rw-r--r--src/dstr-assignment/array-elem-init-simple-no-strict.case22
-rw-r--r--src/dstr-assignment/array-elem-init-simple-strict.case19
-rw-r--r--src/dstr-assignment/array-elem-init-yield-expr.case35
-rw-r--r--src/dstr-assignment/array-elem-init-yield-ident-invalid.case17
-rw-r--r--src/dstr-assignment/array-elem-init-yield-ident-valid.case21
-rw-r--r--src/dstr-assignment/array-elem-iter-get-err.case27
-rw-r--r--src/dstr-assignment/array-elem-iter-nrml-close-err.case44
-rw-r--r--src/dstr-assignment/array-elem-iter-nrml-close-null.case51
-rw-r--r--src/dstr-assignment/array-elem-iter-nrml-close-skip.case43
-rw-r--r--src/dstr-assignment/array-elem-iter-nrml-close.case59
-rw-r--r--src/dstr-assignment/array-elem-iter-rtrn-close-err.case58
-rw-r--r--src/dstr-assignment/array-elem-iter-rtrn-close-null.case54
-rw-r--r--src/dstr-assignment/array-elem-iter-rtrn-close.case65
-rw-r--r--src/dstr-assignment/array-elem-iter-thrw-close-err.case51
-rw-r--r--src/dstr-assignment/array-elem-iter-thrw-close-skip.case44
-rw-r--r--src/dstr-assignment/array-elem-iter-thrw-close.case60
-rw-r--r--src/dstr-assignment/array-elem-nested-array-invalid.case18
-rw-r--r--src/dstr-assignment/array-elem-nested-array-null.case19
-rw-r--r--src/dstr-assignment/array-elem-nested-array-undefined-hole.case19
-rw-r--r--src/dstr-assignment/array-elem-nested-array-undefined-own.case19
-rw-r--r--src/dstr-assignment/array-elem-nested-array-undefined.case19
-rw-r--r--src/dstr-assignment/array-elem-nested-array-yield-expr.case37
-rw-r--r--src/dstr-assignment/array-elem-nested-array-yield-ident-invalid.case18
-rw-r--r--src/dstr-assignment/array-elem-nested-array-yield-ident-valid.case22
-rw-r--r--src/dstr-assignment/array-elem-nested-array.case20
-rw-r--r--src/dstr-assignment/array-elem-nested-obj-invalid.case18
-rw-r--r--src/dstr-assignment/array-elem-nested-obj-null.case19
-rw-r--r--src/dstr-assignment/array-elem-nested-obj-undefined-hole.case19
-rw-r--r--src/dstr-assignment/array-elem-nested-obj-undefined-own.case19
-rw-r--r--src/dstr-assignment/array-elem-nested-obj-undefined.case19
-rw-r--r--src/dstr-assignment/array-elem-nested-obj-yield-expr.case35
-rw-r--r--src/dstr-assignment/array-elem-nested-obj-yield-ident-invalid.case18
-rw-r--r--src/dstr-assignment/array-elem-nested-obj-yield-ident-valid.case22
-rw-r--r--src/dstr-assignment/array-elem-nested-obj.case20
-rw-r--r--src/dstr-assignment/array-elem-put-const.case19
-rw-r--r--src/dstr-assignment/array-elem-put-let.case19
-rw-r--r--src/dstr-assignment/array-elem-put-prop-ref-no-get.case27
-rw-r--r--src/dstr-assignment/array-elem-put-prop-ref-user-err.case23
-rw-r--r--src/dstr-assignment/array-elem-put-prop-ref.case19
-rw-r--r--src/dstr-assignment/array-elem-put-unresolvable-no-strict.case22
-rw-r--r--src/dstr-assignment/array-elem-put-unresolvable-strict.case18
-rw-r--r--src/dstr-assignment/array-elem-target-identifier.case22
-rw-r--r--src/dstr-assignment/array-elem-target-simple-no-strict.case22
-rw-r--r--src/dstr-assignment/array-elem-target-simple-strict.case19
-rw-r--r--src/dstr-assignment/array-elem-target-yield-expr.case37
-rw-r--r--src/dstr-assignment/array-elem-target-yield-invalid.case18
-rw-r--r--src/dstr-assignment/array-elem-target-yield-valid.case22
-rw-r--r--src/dstr-assignment/array-elem-trlg-iter-elision-iter-abpt.case57
-rw-r--r--src/dstr-assignment/array-elem-trlg-iter-elision-iter-nrml-close-err.case53
-rw-r--r--src/dstr-assignment/array-elem-trlg-iter-elision-iter-nrml-close-null.case57
-rw-r--r--src/dstr-assignment/array-elem-trlg-iter-elision-iter-nrml-close-skip.case49
-rw-r--r--src/dstr-assignment/array-elem-trlg-iter-elision-iter-nrml-close.case64
-rw-r--r--src/dstr-assignment/array-elem-trlg-iter-get-err.case28
-rw-r--r--src/dstr-assignment/array-elem-trlg-iter-list-nrml-close-err.case53
-rw-r--r--src/dstr-assignment/array-elem-trlg-iter-list-nrml-close-null.case57
-rw-r--r--src/dstr-assignment/array-elem-trlg-iter-list-nrml-close-skip.case52
-rw-r--r--src/dstr-assignment/array-elem-trlg-iter-list-nrml-close.case65
-rw-r--r--src/dstr-assignment/array-elem-trlg-iter-list-rtrn-close-err.case65
-rw-r--r--src/dstr-assignment/array-elem-trlg-iter-list-rtrn-close-null.case59
-rw-r--r--src/dstr-assignment/array-elem-trlg-iter-list-rtrn-close.case73
-rw-r--r--src/dstr-assignment/array-elem-trlg-iter-list-thrw-close-err.case64
-rw-r--r--src/dstr-assignment/array-elem-trlg-iter-list-thrw-close-skip.case54
-rw-r--r--src/dstr-assignment/array-elem-trlg-iter-list-thrw-close.case66
-rw-r--r--src/dstr-assignment/array-elem-trlg-iter-rest-nrml-close-skip.case50
-rw-r--r--src/dstr-assignment/array-elem-trlg-iter-rest-rtrn-close-err.case74
-rw-r--r--src/dstr-assignment/array-elem-trlg-iter-rest-rtrn-close-null.case66
-rw-r--r--src/dstr-assignment/array-elem-trlg-iter-rest-rtrn-close.case80
-rw-r--r--src/dstr-assignment/array-elem-trlg-iter-rest-thrw-close-err.case64
-rw-r--r--src/dstr-assignment/array-elem-trlg-iter-rest-thrw-close-skip.case55
-rw-r--r--src/dstr-assignment/array-elem-trlg-iter-rest-thrw-close.case68
-rw-r--r--src/dstr-assignment/array-elision-iter-abpt.case44
-rw-r--r--src/dstr-assignment/array-elision-iter-get-err.case26
-rw-r--r--src/dstr-assignment/array-elision-iter-nrml-close-err.case47
-rw-r--r--src/dstr-assignment/array-elision-iter-nrml-close-null.case51
-rw-r--r--src/dstr-assignment/array-elision-iter-nrml-close-skip.case43
-rw-r--r--src/dstr-assignment/array-elision-iter-nrml-close.case59
-rw-r--r--src/dstr-assignment/array-elision-val-array.case13
-rw-r--r--src/dstr-assignment/array-elision-val-bool.case16
-rw-r--r--src/dstr-assignment/array-elision-val-null.case16
-rw-r--r--src/dstr-assignment/array-elision-val-num.case16
-rw-r--r--src/dstr-assignment/array-elision-val-string.case13
-rw-r--r--src/dstr-assignment/array-elision-val-symbol.case19
-rw-r--r--src/dstr-assignment/array-elision-val-undef.case16
-rw-r--r--src/dstr-assignment/array-empty-iter-close-err.case42
-rw-r--r--src/dstr-assignment/array-empty-iter-close-null.case45
-rw-r--r--src/dstr-assignment/array-empty-iter-close.case53
-rw-r--r--src/dstr-assignment/array-empty-iter-get-err.case26
-rw-r--r--src/dstr-assignment/array-empty-val-array.case15
-rw-r--r--src/dstr-assignment/array-empty-val-bool.case17
-rw-r--r--src/dstr-assignment/array-empty-val-null.case17
-rw-r--r--src/dstr-assignment/array-empty-val-num.case17
-rw-r--r--src/dstr-assignment/array-empty-val-string.case15
-rw-r--r--src/dstr-assignment/array-empty-val-symbol.case19
-rw-r--r--src/dstr-assignment/array-empty-val-undef.case17
-rw-r--r--src/dstr-assignment/array-iteration.case27
-rw-r--r--src/dstr-assignment/array-rest-after-element.case22
-rw-r--r--src/dstr-assignment/array-rest-after-elision.case21
-rw-r--r--src/dstr-assignment/array-rest-before-element.case16
-rw-r--r--src/dstr-assignment/array-rest-before-elision.case16
-rw-r--r--src/dstr-assignment/array-rest-before-rest.case16
-rw-r--r--src/dstr-assignment/array-rest-elision-invalid.case16
-rw-r--r--src/dstr-assignment/array-rest-elision-iter-abpt.case50
-rw-r--r--src/dstr-assignment/array-rest-elision.case22
-rw-r--r--src/dstr-assignment/array-rest-init.case17
-rw-r--r--src/dstr-assignment/array-rest-iter-get-err.case27
-rw-r--r--src/dstr-assignment/array-rest-iter-nrml-close-skip.case46
-rw-r--r--src/dstr-assignment/array-rest-iter-rtrn-close-err.case70
-rw-r--r--src/dstr-assignment/array-rest-iter-rtrn-close-null.case66
-rw-r--r--src/dstr-assignment/array-rest-iter-rtrn-close.case81
-rw-r--r--src/dstr-assignment/array-rest-iter-thrw-close-err.case64
-rw-r--r--src/dstr-assignment/array-rest-iter-thrw-close-skip.case45
-rw-r--r--src/dstr-assignment/array-rest-iter-thrw-close.case72
-rw-r--r--src/dstr-assignment/array-rest-iteration.case28
-rw-r--r--src/dstr-assignment/array-rest-lref-err.case56
-rw-r--r--src/dstr-assignment/array-rest-lref.case53
-rw-r--r--src/dstr-assignment/array-rest-nested-array-invalid.case18
-rw-r--r--src/dstr-assignment/array-rest-nested-array-iter-thrw-close-skip.case59
-rw-r--r--src/dstr-assignment/array-rest-nested-array-null.case21
-rw-r--r--src/dstr-assignment/array-rest-nested-array-undefined-hole.case20
-rw-r--r--src/dstr-assignment/array-rest-nested-array-undefined-own.case20
-rw-r--r--src/dstr-assignment/array-rest-nested-array-undefined.case20
-rw-r--r--src/dstr-assignment/array-rest-nested-array-yield-expr.case37
-rw-r--r--src/dstr-assignment/array-rest-nested-array-yield-ident-invalid.case18
-rw-r--r--src/dstr-assignment/array-rest-nested-array-yield-ident-valid.case22
-rw-r--r--src/dstr-assignment/array-rest-nested-array.case20
-rw-r--r--src/dstr-assignment/array-rest-nested-obj-invalid.case18
-rw-r--r--src/dstr-assignment/array-rest-nested-obj-null.case21
-rw-r--r--src/dstr-assignment/array-rest-nested-obj-undefined-hole.case22
-rw-r--r--src/dstr-assignment/array-rest-nested-obj-undefined-own.case22
-rw-r--r--src/dstr-assignment/array-rest-nested-obj-undefined.case22
-rw-r--r--src/dstr-assignment/array-rest-nested-obj-yield-expr.case35
-rw-r--r--src/dstr-assignment/array-rest-nested-obj-yield-ident-invalid.case18
-rw-r--r--src/dstr-assignment/array-rest-nested-obj-yield-ident-valid.case22
-rw-r--r--src/dstr-assignment/array-rest-nested-obj.case20
-rw-r--r--src/dstr-assignment/array-rest-put-const.case19
-rw-r--r--src/dstr-assignment/array-rest-put-let.case19
-rw-r--r--src/dstr-assignment/array-rest-put-prop-ref-no-get.case30
-rw-r--r--src/dstr-assignment/array-rest-put-prop-ref-user-err-iter-close-skip.case62
-rw-r--r--src/dstr-assignment/array-rest-put-prop-ref-user-err.case23
-rw-r--r--src/dstr-assignment/array-rest-put-prop-ref.case22
-rw-r--r--src/dstr-assignment/array-rest-put-unresolvable-no-strict.case22
-rw-r--r--src/dstr-assignment/array-rest-put-unresolvable-strict.case18
-rw-r--r--src/dstr-assignment/array-rest-yield-expr.case39
-rw-r--r--src/dstr-assignment/array-rest-yield-ident-invalid.case20
-rw-r--r--src/dstr-assignment/array-rest-yield-ident-valid.case25
-rw-r--r--src/dstr-assignment/default/assignment-expr.template27
-rw-r--r--src/dstr-assignment/default/for-of.template36
-rw-r--r--src/dstr-assignment/error/assignment-expr.template22
-rw-r--r--src/dstr-assignment/error/for-of.template38
-rw-r--r--src/dstr-assignment/obj-empty-bool.case15
-rw-r--r--src/dstr-assignment/obj-empty-null.case17
-rw-r--r--src/dstr-assignment/obj-empty-num.case15
-rw-r--r--src/dstr-assignment/obj-empty-obj.case15
-rw-r--r--src/dstr-assignment/obj-empty-string.case15
-rw-r--r--src/dstr-assignment/obj-empty-symbol.case18
-rw-r--r--src/dstr-assignment/obj-empty-undef.case17
-rw-r--r--src/dstr-assignment/obj-id-identifier-resolution-first.case18
-rw-r--r--src/dstr-assignment/obj-id-identifier-resolution-last.case18
-rw-r--r--src/dstr-assignment/obj-id-identifier-resolution-lone.case17
-rw-r--r--src/dstr-assignment/obj-id-identifier-resolution-middle.case18
-rw-r--r--src/dstr-assignment/obj-id-identifier-resolution-trlng.case18
-rw-r--r--src/dstr-assignment/obj-id-identifier-yield-expr.case22
-rw-r--r--src/dstr-assignment/obj-id-identifier-yield-ident-invalid.case17
-rw-r--r--src/dstr-assignment/obj-id-identifier-yield-ident-valid.case20
-rw-r--r--src/dstr-assignment/obj-id-init-assignment-missing.case20
-rw-r--r--src/dstr-assignment/obj-id-init-assignment-null.case20
-rw-r--r--src/dstr-assignment/obj-id-init-assignment-truthy.case20
-rw-r--r--src/dstr-assignment/obj-id-init-assignment-undef.case20
-rw-r--r--src/dstr-assignment/obj-id-init-evaluation.case21
-rw-r--r--src/dstr-assignment/obj-id-init-fn-name-arrow.case31
-rw-r--r--src/dstr-assignment/obj-id-init-fn-name-class.case34
-rw-r--r--src/dstr-assignment/obj-id-init-fn-name-cover.case34
-rw-r--r--src/dstr-assignment/obj-id-init-fn-name-fn.case33
-rw-r--r--src/dstr-assignment/obj-id-init-fn-name-gen.case34
-rw-r--r--src/dstr-assignment/obj-id-init-in.case18
-rw-r--r--src/dstr-assignment/obj-id-init-let.case21
-rw-r--r--src/dstr-assignment/obj-id-init-order.case21
-rw-r--r--src/dstr-assignment/obj-id-init-simple-no-strict.case20
-rw-r--r--src/dstr-assignment/obj-id-init-simple-strict.case17
-rw-r--r--src/dstr-assignment/obj-id-init-yield-expr.case35
-rw-r--r--src/dstr-assignment/obj-id-init-yield-ident-invalid.case18
-rw-r--r--src/dstr-assignment/obj-id-init-yield-ident-valid.case22
-rw-r--r--src/dstr-assignment/obj-id-put-const.case19
-rw-r--r--src/dstr-assignment/obj-id-put-let.case19
-rw-r--r--src/dstr-assignment/obj-id-put-unresolvable-no-strict.case22
-rw-r--r--src/dstr-assignment/obj-id-put-unresolvable-strict.case18
-rw-r--r--src/dstr-assignment/obj-id-simple-no-strict.case20
-rw-r--r--src/dstr-assignment/obj-id-simple-strict.case17
-rw-r--r--src/dstr-assignment/obj-prop-elem-init-assignment-missing.case20
-rw-r--r--src/dstr-assignment/obj-prop-elem-init-assignment-null.case19
-rw-r--r--src/dstr-assignment/obj-prop-elem-init-assignment-truthy.case19
-rw-r--r--src/dstr-assignment/obj-prop-elem-init-assignment-undef.case19
-rw-r--r--src/dstr-assignment/obj-prop-elem-init-evaluation.case23
-rw-r--r--src/dstr-assignment/obj-prop-elem-init-fn-name-arrow.case32
-rw-r--r--src/dstr-assignment/obj-prop-elem-init-fn-name-class.case35
-rw-r--r--src/dstr-assignment/obj-prop-elem-init-fn-name-cover.case35
-rw-r--r--src/dstr-assignment/obj-prop-elem-init-fn-name-fn.case34
-rw-r--r--src/dstr-assignment/obj-prop-elem-init-fn-name-gen.case35
-rw-r--r--src/dstr-assignment/obj-prop-elem-init-in.case18
-rw-r--r--src/dstr-assignment/obj-prop-elem-init-let.case21
-rw-r--r--src/dstr-assignment/obj-prop-elem-init-yield-expr.case34
-rw-r--r--src/dstr-assignment/obj-prop-elem-init-yield-ident-invalid.case18
-rw-r--r--src/dstr-assignment/obj-prop-elem-init-yield-ident-valid.case22
-rw-r--r--src/dstr-assignment/obj-prop-elem-target-yield-expr.case36
-rw-r--r--src/dstr-assignment/obj-prop-elem-target-yield-ident-invalid.case18
-rw-r--r--src/dstr-assignment/obj-prop-elem-target-yield-ident-valid.case22
-rw-r--r--src/dstr-assignment/obj-prop-identifier-resolution-first.case19
-rw-r--r--src/dstr-assignment/obj-prop-identifier-resolution-last.case19
-rw-r--r--src/dstr-assignment/obj-prop-identifier-resolution-lone.case18
-rw-r--r--src/dstr-assignment/obj-prop-identifier-resolution-middle.case19
-rw-r--r--src/dstr-assignment/obj-prop-identifier-resolution-trlng.case19
-rw-r--r--src/dstr-assignment/obj-prop-name-evaluation-error.case19
-rw-r--r--src/dstr-assignment/obj-prop-name-evaluation.case20
-rw-r--r--src/dstr-assignment/obj-prop-nested-array-invalid.case18
-rw-r--r--src/dstr-assignment/obj-prop-nested-array-null.case19
-rw-r--r--src/dstr-assignment/obj-prop-nested-array-undefined-own.case19
-rw-r--r--src/dstr-assignment/obj-prop-nested-array-undefined.case19
-rw-r--r--src/dstr-assignment/obj-prop-nested-array-yield-expr.case35
-rw-r--r--src/dstr-assignment/obj-prop-nested-array-yield-ident-invalid.case18
-rw-r--r--src/dstr-assignment/obj-prop-nested-array-yield-ident-valid.case22
-rw-r--r--src/dstr-assignment/obj-prop-nested-array.case20
-rw-r--r--src/dstr-assignment/obj-prop-nested-obj-invalid.case19
-rw-r--r--src/dstr-assignment/obj-prop-nested-obj-null.case19
-rw-r--r--src/dstr-assignment/obj-prop-nested-obj-undefined-own.case19
-rw-r--r--src/dstr-assignment/obj-prop-nested-obj-undefined.case19
-rw-r--r--src/dstr-assignment/obj-prop-nested-obj-yield-expr.case35
-rw-r--r--src/dstr-assignment/obj-prop-nested-obj-yield-ident-invalid.case18
-rw-r--r--src/dstr-assignment/obj-prop-nested-obj-yield-ident-valid.case22
-rw-r--r--src/dstr-assignment/obj-prop-nested-obj.case20
-rw-r--r--src/dstr-assignment/obj-prop-put-const.case19
-rw-r--r--src/dstr-assignment/obj-prop-put-let.case19
-rw-r--r--src/dstr-assignment/obj-prop-put-order.case19
-rw-r--r--src/dstr-assignment/obj-prop-put-prop-ref-no-get.case27
-rw-r--r--src/dstr-assignment/obj-prop-put-prop-ref-user-err.case23
-rw-r--r--src/dstr-assignment/obj-prop-put-prop-ref.case19
-rw-r--r--src/dstr-assignment/obj-prop-put-unresolvable-no-strict.case22
-rw-r--r--src/dstr-assignment/obj-prop-put-unresolvable-strict.case18
-rw-r--r--src/dstr-assignment/syntax/assignment-expr.template20
-rw-r--r--src/dstr-assignment/syntax/for-in.template29
-rw-r--r--src/dstr-assignment/syntax/for-of.template29
250 files changed, 7347 insertions, 0 deletions
diff --git a/src/dstr-assignment/array-elem-init-assignment.case b/src/dstr-assignment/array-elem-init-assignment.case
new file mode 100644
index 000000000..a03405902
--- /dev/null
+++ b/src/dstr-assignment/array-elem-init-assignment.case
@@ -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.
+
+/*---
+desc: >
+ If the Initializer is present and v is undefined, the Initializer should be
+ evaluated and the result assigned to the target reference.
+template: default
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var v2, vNull, vHole, vUndefined, vOob;
+//- elems
+[v2 = 10, vNull = 11, vHole = 12, vUndefined = 13, vOob = 14]
+//- vals
+[2, null, , undefined]
+//- body
+assert.sameValue(v2, 2);
+assert.sameValue(vNull, null);
+assert.sameValue(vHole, 12);
+assert.sameValue(vUndefined, 13);
+assert.sameValue(vOob, 14);
diff --git a/src/dstr-assignment/array-elem-init-evaluation.case b/src/dstr-assignment/array-elem-init-evaluation.case
new file mode 100644
index 000000000..5feea93a8
--- /dev/null
+++ b/src/dstr-assignment/array-elem-init-evaluation.case
@@ -0,0 +1,20 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ The Initializer should only be evaluated if v is undefined.
+template: default
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var flag1 = false, flag2 = false;
+var _;
+//- elems
+[ _ = flag1 = true, _ = flag2 = true ]
+//- vals
+[14]
+//- body
+assert.sameValue(flag1, false);
+assert.sameValue(flag2, true);
diff --git a/src/dstr-assignment/array-elem-init-fn-name-arrow.case b/src/dstr-assignment/array-elem-init-fn-name-arrow.case
new file mode 100644
index 000000000..75d60e512
--- /dev/null
+++ b/src/dstr-assignment/array-elem-init-fn-name-arrow.case
@@ -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.
+
+/*---
+desc: Assignment of function `name` attribute (ArrowFunction)
+template: default
+es6id: 12.14.5.3
+info: >
+ 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)).
+includes: [propertyHelper.js]
+---*/
+
+//- setup
+var arrow;
+//- elems
+[ arrow = () => {} ]
+//- vals
+[]
+//- body
+assert.sameValue(arrow.name, 'arrow');
+verifyNotEnumerable(arrow, 'name');
+verifyNotWritable(arrow, 'name');
+verifyConfigurable(arrow, 'name');
diff --git a/src/dstr-assignment/array-elem-init-fn-name-class.case b/src/dstr-assignment/array-elem-init-fn-name-class.case
new file mode 100644
index 000000000..91be89097
--- /dev/null
+++ b/src/dstr-assignment/array-elem-init-fn-name-class.case
@@ -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.
+
+/*---
+desc: Assignment of function `name` attribute (ClassExpression)
+template: default
+es6id: 12.14.5.3
+info: >
+ 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)).
+includes: [propertyHelper.js]
+features: [class]
+---*/
+
+//- setup
+var xCls, cls;
+//- elems
+[ xCls = class x {},cls = class {} ]
+//- vals
+[]
+//- body
+assert(xCls.name !== 'xCls');
+
+assert.sameValue(cls.name, 'cls');
+verifyNotEnumerable(cls, 'name');
+verifyNotWritable(cls, 'name');
+verifyConfigurable(cls, 'name');
diff --git a/src/dstr-assignment/array-elem-init-fn-name-cover.case b/src/dstr-assignment/array-elem-init-fn-name-cover.case
new file mode 100644
index 000000000..43cb36948
--- /dev/null
+++ b/src/dstr-assignment/array-elem-init-fn-name-cover.case
@@ -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.
+
+/*---
+desc: >
+ Assignment of function `name` attribute (CoverParenthesizedExpression)
+template: default
+es6id: 12.14.5.3
+info: >
+ 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)).
+includes: [propertyHelper.js]
+---*/
+
+//- setup
+var xCover, cover;
+//- elems
+[ xCover = (0, function() {}), cover = (function() {}) ]
+//- vals
+[]
+//- body
+assert(xCover.name !== 'xCover');
+
+assert.sameValue(cover.name, 'cover');
+verifyNotEnumerable(cover, 'name');
+verifyNotWritable(cover, 'name');
+verifyConfigurable(cover, 'name');
diff --git a/src/dstr-assignment/array-elem-init-fn-name-fn.case b/src/dstr-assignment/array-elem-init-fn-name-fn.case
new file mode 100644
index 000000000..4493b8e04
--- /dev/null
+++ b/src/dstr-assignment/array-elem-init-fn-name-fn.case
@@ -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.
+
+/*---
+desc: Assignment of function `name` attribute (FunctionExpression)
+template: default
+es6id: 12.14.5.3
+info: >
+ 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)).
+includes: [propertyHelper.js]
+features: [class]
+---*/
+
+//- setup
+var xFn, fn;
+//- elems
+[ xFn = function x() {}, fn = function() {} ]
+//- vals
+[]
+//- body
+assert(xFn.name !== 'xFn');
+
+assert.sameValue(fn.name, 'fn');
+verifyNotEnumerable(fn, 'name');
+verifyNotWritable(fn, 'name');
+verifyConfigurable(fn, 'name');
diff --git a/src/dstr-assignment/array-elem-init-fn-name-gen.case b/src/dstr-assignment/array-elem-init-fn-name-gen.case
new file mode 100644
index 000000000..fea3bbaa2
--- /dev/null
+++ b/src/dstr-assignment/array-elem-init-fn-name-gen.case
@@ -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.
+
+/*---
+desc: Assignment of function `name` attribute (GeneratorExpression)
+template: default
+es6id: 12.14.5.3
+info: >
+ 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)).
+includes: [propertyHelper.js]
+features: [generators]
+---*/
+
+//- setup
+var xGen, gen;
+//- elems
+[ xGen = function* x() {}, gen = function*() {} ]
+//- vals
+[]
+//- body
+assert.notSameValue(xGen.name, 'xGen');
+
+assert.sameValue(gen.name, 'gen');
+verifyNotEnumerable(gen, 'name');
+verifyNotWritable(gen, 'name');
+verifyConfigurable(gen, 'name');
diff --git a/src/dstr-assignment/array-elem-init-in.case b/src/dstr-assignment/array-elem-init-in.case
new file mode 100644
index 000000000..d3afbe276
--- /dev/null
+++ b/src/dstr-assignment/array-elem-init-in.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ The Initializer in an AssignmentElement may be an `in` expression.
+template: default
+es6id: 12.14.5
+---*/
+
+//- setup
+var x;
+//- elems
+[ x = 'x' in {} ]
+//- vals
+[]
+//- body
+assert.sameValue(x, false);
diff --git a/src/dstr-assignment/array-elem-init-let.case b/src/dstr-assignment/array-elem-init-let.case
new file mode 100644
index 000000000..b3b8aea28
--- /dev/null
+++ b/src/dstr-assignment/array-elem-init-let.case
@@ -0,0 +1,21 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ Value retrieval of Initializer obeys `let` semantics.
+template: error
+es6id: 12.14.5.3
+features: [let]
+---*/
+
+//- error
+ReferenceError
+//- setup
+var x;
+//- elems
+[ x = y ]
+//- vals
+[]
+//- teardown
+let y;
diff --git a/src/dstr-assignment/array-elem-init-order.case b/src/dstr-assignment/array-elem-init-order.case
new file mode 100644
index 000000000..f6e483024
--- /dev/null
+++ b/src/dstr-assignment/array-elem-init-order.case
@@ -0,0 +1,21 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ Initializer values should be assigned in left-to-right order.
+template: default
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var x = 0;
+var a, b;
+//- elems
+[ a = x += 1, b = x *= 2 ]
+//- vals
+[]
+//- body
+assert.sameValue(a, 1);
+assert.sameValue(b, 2);
+assert.sameValue(x, 2);
diff --git a/src/dstr-assignment/array-elem-init-simple-no-strict.case b/src/dstr-assignment/array-elem-init-simple-no-strict.case
new file mode 100644
index 000000000..200238d07
--- /dev/null
+++ b/src/dstr-assignment/array-elem-init-simple-no-strict.case
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ Identifiers that appear as the DestructuringAssignmentTarget in an
+ AssignmentElement should take on the iterated value corresponding to their
+ position in the ArrayAssignmentPattern.
+template: default
+es6id: 12.14.5.3
+flags: [noStrict]
+---*/
+
+//- setup
+var argument, eval;
+//- elems
+[arguments = 4, eval = 5]
+//- vals
+[]
+//- body
+assert.sameValue(arguments, 4);
+assert.sameValue(eval, 5);
diff --git a/src/dstr-assignment/array-elem-init-simple-strict.case b/src/dstr-assignment/array-elem-init-simple-strict.case
new file mode 100644
index 000000000..7158a328b
--- /dev/null
+++ b/src/dstr-assignment/array-elem-init-simple-strict.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ It is a Syntax Error if LeftHandSideExpression is neither an
+ ObjectLiteral nor an ArrayLiteral and
+ IsValidSimpleAssignmentTarget(LeftHandSideExpression) is
+ false.
+template: syntax
+es6id: 12.14.5.1
+flags: [onlyStrict]
+negative: SyntaxError
+---*/
+
+//- elems
+[arguments]
+//- values
+[]
diff --git a/src/dstr-assignment/array-elem-init-yield-expr.case b/src/dstr-assignment/array-elem-init-yield-expr.case
new file mode 100644
index 000000000..6aa3a97ed
--- /dev/null
+++ b/src/dstr-assignment/array-elem-init-yield-expr.case
@@ -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.
+
+/*---
+desc: >
+ When a `yield` token appears within the Initializer of an
+ AssignmentElement within a generator function body, it behaves as a
+ YieldExpression.
+template: default
+es6id: 12.14.5.4
+features: [generators]
+---*/
+
+//- setup
+var value = [];
+var iterationResult, iter, x;
+iter = (function*() {
+//- elems
+[ x = yield ]
+//- vals
+[]
+//- teardown
+})();
+
+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);
diff --git a/src/dstr-assignment/array-elem-init-yield-ident-invalid.case b/src/dstr-assignment/array-elem-init-yield-ident-invalid.case
new file mode 100644
index 000000000..c67ee2c34
--- /dev/null
+++ b/src/dstr-assignment/array-elem-init-yield-ident-invalid.case
@@ -0,0 +1,17 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When a `yield` token appears within the Initializer of an AssignmentElement
+ outside of a generator function body, it behaves as an IdentifierReference.
+template: syntax
+es6id: 12.14.5.4
+flags: [onlyStrict]
+negative: SyntaxError
+---*/
+
+//- elems
+[ x = yield ]
+//- vals
+[]
diff --git a/src/dstr-assignment/array-elem-init-yield-ident-valid.case b/src/dstr-assignment/array-elem-init-yield-ident-valid.case
new file mode 100644
index 000000000..05b7baac6
--- /dev/null
+++ b/src/dstr-assignment/array-elem-init-yield-ident-valid.case
@@ -0,0 +1,21 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When a `yield` token appears within the Initializer of an AssignmentElement
+ outside of a generator function body, it behaves as an IdentifierReference.
+template: default
+es6id: 12.14.5.4
+flags: [noStrict]
+---*/
+
+//- setup
+var yield = 4;
+var x;
+//- elems
+[ x = yield ]
+//- vals
+[]
+//- body
+assert.sameValue(x, 4);
diff --git a/src/dstr-assignment/array-elem-iter-get-err.case b/src/dstr-assignment/array-elem-iter-get-err.case
new file mode 100644
index 000000000..ed4a51ffa
--- /dev/null
+++ b/src/dstr-assignment/array-elem-iter-get-err.case
@@ -0,0 +1,27 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: Abrupt completion returned from GetIterator
+info: |
+ ArrayAssignmentPattern : [ AssignmentElementList ]
+
+ 1. Let iterator be GetIterator(value).
+ 2. ReturnIfAbrupt(iterator).
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+var iterable = {};
+iterable[Symbol.iterator] = function() {
+ throw new Test262Error();
+};
+var _;
+//- error
+Test262Error
+//- elems
+[ _ ]
+//- vals
+iterable
diff --git a/src/dstr-assignment/array-elem-iter-nrml-close-err.case b/src/dstr-assignment/array-elem-iter-nrml-close-err.case
new file mode 100644
index 000000000..197b79a77
--- /dev/null
+++ b/src/dstr-assignment/array-elem-iter-nrml-close-err.case
@@ -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.
+/*---
+desc: Abrupt completion returned from IteratorClose
+info: |
+ ArrayAssignmentPattern : [ AssignmentElementList ]
+
+ [...]
+ 5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator, result).
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- elems
+[ _ ]
+//- vals
+iterable
+//- error
+Test262Error
+//- teardown
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 1);
diff --git a/src/dstr-assignment/array-elem-iter-nrml-close-null.case b/src/dstr-assignment/array-elem-iter-nrml-close-null.case
new file mode 100644
index 000000000..37314b7c1
--- /dev/null
+++ b/src/dstr-assignment/array-elem-iter-nrml-close-null.case
@@ -0,0 +1,51 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose throws a TypeError when `return` returns a non-Object value
+info: |
+ 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.
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- elems
+[ _ ]
+//- vals
+iterable
+//- error
+TypeError
diff --git a/src/dstr-assignment/array-elem-iter-nrml-close-skip.case b/src/dstr-assignment/array-elem-iter-nrml-close-skip.case
new file mode 100644
index 000000000..5ae291334
--- /dev/null
+++ b/src/dstr-assignment/array-elem-iter-nrml-close-skip.case
@@ -0,0 +1,43 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is not called when assignment evaluation has exhausted the
+ iterator
+info: |
+ ArrayAssignmentPattern : [ AssignmentElementList ]
+
+ [...]
+ 5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator, result).
+ 6. Return result.
+features: [Symbol.iterator]
+template: default
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- elems
+[ _ ]
+//- vals
+iterable
+//- body
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
diff --git a/src/dstr-assignment/array-elem-iter-nrml-close.case b/src/dstr-assignment/array-elem-iter-nrml-close.case
new file mode 100644
index 000000000..f66f0ccda
--- /dev/null
+++ b/src/dstr-assignment/array-elem-iter-nrml-close.case
@@ -0,0 +1,59 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is called when assignment evaluation has not exhausted the
+ iterator
+info: |
+ 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, « »).
+ [...]
+features: [Symbol.iterator]
+template: default
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- elems
+[ _ ]
+//- vals
+iterable
+//- body
+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');
diff --git a/src/dstr-assignment/array-elem-iter-rtrn-close-err.case b/src/dstr-assignment/array-elem-iter-rtrn-close-err.case
new file mode 100644
index 000000000..3742cf150
--- /dev/null
+++ b/src/dstr-assignment/array-elem-iter-rtrn-close-err.case
@@ -0,0 +1,58 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is called when reference evaluation produces a "return"
+ completion
+info: |
+ 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).
+features: [Symbol.iterator, generators]
+template: default
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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() {
+//- elems
+[ {}[ yield ] ]
+//- vals
+iterable
+//- body
+unreachable += 1;
+//- teardown
+}
+iter = g();
+iter.next();
+assert.throws(Test262Error, function() {
+ iter.return();
+});
+
+assert.sameValue(returnCount, 1);
+assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
diff --git a/src/dstr-assignment/array-elem-iter-rtrn-close-null.case b/src/dstr-assignment/array-elem-iter-rtrn-close-null.case
new file mode 100644
index 000000000..817ca7b6b
--- /dev/null
+++ b/src/dstr-assignment/array-elem-iter-rtrn-close-null.case
@@ -0,0 +1,54 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose throws a TypeError when `return` returns a non-Object value
+info: |
+ 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.
+features: [Symbol.iterator, generators]
+template: default
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+var iterable = {};
+var iterator = {
+ return: function() {
+ return null;
+ }
+};
+var iter;
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+function* g() {
+//- elems
+[ {}[yield] ]
+//- vals
+iterable
+//- body
+ unreachable += 1;
+//- teardown
+}
+
+iter = g();
+iter.next();
+
+assert.throws(TypeError, function() {
+ iter.return();
+});
diff --git a/src/dstr-assignment/array-elem-iter-rtrn-close.case b/src/dstr-assignment/array-elem-iter-rtrn-close.case
new file mode 100644
index 000000000..7f1c482fe
--- /dev/null
+++ b/src/dstr-assignment/array-elem-iter-rtrn-close.case
@@ -0,0 +1,65 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is called when reference evaluation produces a "return"
+ completion
+info: |
+ 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).
+features: [Symbol.iterator, generators]
+template: default
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+var returnCount = 0;
+var unreachable = 0;
+var thisValue = null;
+var args = null;
+var iterable = {};
+var iterator = {
+ return: function() {
+ returnCount += 1;
+ thisValue = this;
+ args = arguments;
+ return {};
+ }
+};
+var iter, result;
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+function* g() {
+//- elems
+[ {}[yield] ]
+//- vals
+iterable
+//- body
+unreachable += 1;
+//- teardown
+}
+iter = g();
+iter.next();
+result = iter.return(777);
+
+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');
diff --git a/src/dstr-assignment/array-elem-iter-thrw-close-err.case b/src/dstr-assignment/array-elem-iter-thrw-close-err.case
new file mode 100644
index 000000000..04c4da8cc
--- /dev/null
+++ b/src/dstr-assignment/array-elem-iter-thrw-close-err.case
@@ -0,0 +1,51 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is called when reference evaluation produces a "throw"
+ completion
+info: |
+ ArrayAssignmentPattern : [ AssignmentElementList ]
+
+ [...]
+ 5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+ 6. Return result.
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- error
+Test262Error
+//- elems
+[ {}[thrower()] ]
+//- vals
+iterable
+//- teardown
+assert.sameValue(nextCount, 0);
+assert.sameValue(returnCount, 1);
diff --git a/src/dstr-assignment/array-elem-iter-thrw-close-skip.case b/src/dstr-assignment/array-elem-iter-thrw-close-skip.case
new file mode 100644
index 000000000..7ac68788d
--- /dev/null
+++ b/src/dstr-assignment/array-elem-iter-thrw-close-skip.case
@@ -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.
+/*---
+desc: >
+ IteratorClose is not called when iteration produces an abrupt completion
+info: |
+ ArrayAssignmentPattern : [ AssignmentElementList ]
+
+ [...]
+ 5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+ 6. Return result.
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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 _;
+//- error
+Test262Error
+//- elems
+[ x ]
+//- vals
+iterable
+//- teardown
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
diff --git a/src/dstr-assignment/array-elem-iter-thrw-close.case b/src/dstr-assignment/array-elem-iter-thrw-close.case
new file mode 100644
index 000000000..17129f09d
--- /dev/null
+++ b/src/dstr-assignment/array-elem-iter-thrw-close.case
@@ -0,0 +1,60 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is called when reference evaluation produces a "throw"
+ completion
+info: |
+ 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, « »).
+ [...]
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- error
+Test262Error
+//- elems
+[ {}[thrower()] ]
+//- vals
+iterable
+//- teardown
+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');
diff --git a/src/dstr-assignment/array-elem-nested-array-invalid.case b/src/dstr-assignment/array-elem-nested-array-invalid.case
new file mode 100644
index 000000000..9cceb9f06
--- /dev/null
+++ b/src/dstr-assignment/array-elem-nested-array-invalid.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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.
+template: syntax
+es6id: 12.14.5.1
+negative: SyntaxError
+---*/
+
+//- elems
+[[(x, y)]]
+//- vals
+[[]]
diff --git a/src/dstr-assignment/array-elem-nested-array-null.case b/src/dstr-assignment/array-elem-nested-array-null.case
new file mode 100644
index 000000000..5910534f2
--- /dev/null
+++ b/src/dstr-assignment/array-elem-nested-array-null.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When DestructuringAssignmentTarget is an array literal and the value is
+ `null`, a TypeError should be thrown.
+template: error
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var _;
+//- error
+TypeError
+//- elems
+[[ _ ]]
+//- vals
+[null]
diff --git a/src/dstr-assignment/array-elem-nested-array-undefined-hole.case b/src/dstr-assignment/array-elem-nested-array-undefined-hole.case
new file mode 100644
index 000000000..f0561b8be
--- /dev/null
+++ b/src/dstr-assignment/array-elem-nested-array-undefined-hole.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When DestructuringAssignmentTarget is an array literal and the value is a
+ "hole", a TypeError should be thrown.
+template: error
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var _;
+//- error
+TypeError
+//- elems
+[[ _ ]]
+//- vals
+[ , ]
diff --git a/src/dstr-assignment/array-elem-nested-array-undefined-own.case b/src/dstr-assignment/array-elem-nested-array-undefined-own.case
new file mode 100644
index 000000000..1972f02ee
--- /dev/null
+++ b/src/dstr-assignment/array-elem-nested-array-undefined-own.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When DestructuringAssignmentTarget is an array literal and the value is
+ `undefined`, a TypeError should be thrown.
+template: error
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var _;
+//- error
+TypeError
+//- elems
+[[ x ]]
+//- vals
+[undefined]
diff --git a/src/dstr-assignment/array-elem-nested-array-undefined.case b/src/dstr-assignment/array-elem-nested-array-undefined.case
new file mode 100644
index 000000000..6b07a4f03
--- /dev/null
+++ b/src/dstr-assignment/array-elem-nested-array-undefined.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When DestructuringAssignmentTarget is an array literal and no value is
+ defined, a TypeError should be thrown.
+template: error
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var _;
+//- error
+TypeError
+//- elems
+[[ x ]]
+//- vals
+[]
diff --git a/src/dstr-assignment/array-elem-nested-array-yield-expr.case b/src/dstr-assignment/array-elem-nested-array-yield-expr.case
new file mode 100644
index 000000000..bd5d94ffa
--- /dev/null
+++ b/src/dstr-assignment/array-elem-nested-array-yield-expr.case
@@ -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.
+
+/*---
+desc: >
+ When a `yield` token appears within the DestructuringAssignmentTarget of a
+ nested destructuring assignment and within a generator function body, it
+ behaves as a YieldExpression.
+template: default
+es6id: 12.14.5.3
+features: [generators]
+---*/
+
+//- setup
+var value = [[22]];
+var x = {};
+var iterationResult, iter;
+
+iter = (function*() {
+//- elems
+[[x[yield]]]
+//- vals
+value
+//- teardown
+}());
+
+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);
diff --git a/src/dstr-assignment/array-elem-nested-array-yield-ident-invalid.case b/src/dstr-assignment/array-elem-nested-array-yield-ident-invalid.case
new file mode 100644
index 000000000..006428417
--- /dev/null
+++ b/src/dstr-assignment/array-elem-nested-array-yield-ident-invalid.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When a `yield` token appears within the DestructuringAssignmentTarget of a
+ nested destructuring assignment outside of strict mode, it behaves as an
+ IdentifierReference.
+template: syntax
+es6id: 12.14.5.3
+flags: [onlyStrict]
+negative: SyntaxError
+---*/
+
+//- elems
+[[x[yield]]]
+//- vals
+[[]]
diff --git a/src/dstr-assignment/array-elem-nested-array-yield-ident-valid.case b/src/dstr-assignment/array-elem-nested-array-yield-ident-valid.case
new file mode 100644
index 000000000..c1bcd3c67
--- /dev/null
+++ b/src/dstr-assignment/array-elem-nested-array-yield-ident-valid.case
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When a `yield` token appears within the DestructuringAssignmentTarget of a
+ nested destructuring assignment outside of strict mode, it behaves as an
+ IdentifierReference.
+template: default
+es6id: 12.14.5.3
+flags: [noStrict]
+---*/
+
+//- setup
+var yield = 'prop';
+var x = {};
+//- elems
+[[x[yield]]]
+//- vals
+[[22]]
+//- body
+assert.sameValue(x.prop, 22);
diff --git a/src/dstr-assignment/array-elem-nested-array.case b/src/dstr-assignment/array-elem-nested-array.case
new file mode 100644
index 000000000..7c5902abf
--- /dev/null
+++ b/src/dstr-assignment/array-elem-nested-array.case
@@ -0,0 +1,20 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When DestructuringAssignmentTarget is an array literal, it should be parsed
+ parsed as a DestructuringAssignmentPattern and evaluated as a destructuring
+ assignment.
+template: default
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var x;
+//- elems
+[[x]]
+//- vals
+[[1]]
+//- body
+assert.sameValue(x, 1);
diff --git a/src/dstr-assignment/array-elem-nested-obj-invalid.case b/src/dstr-assignment/array-elem-nested-obj-invalid.case
new file mode 100644
index 000000000..3bf2ec0f3
--- /dev/null
+++ b/src/dstr-assignment/array-elem-nested-obj-invalid.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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.
+template: syntax
+es6id: 12.14.5.1
+negative: SyntaxError
+---*/
+
+//- elems
+[{ get x() {} }]
+//- vals
+[{}]
diff --git a/src/dstr-assignment/array-elem-nested-obj-null.case b/src/dstr-assignment/array-elem-nested-obj-null.case
new file mode 100644
index 000000000..fb7284381
--- /dev/null
+++ b/src/dstr-assignment/array-elem-nested-obj-null.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When DestructuringAssignmentTarget is an object literal and the value is
+ `null`, a TypeError should be thrown.
+template: error
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var x;
+//- error
+TypeError
+//- elems
+[{ x }]
+//- vals
+[null]
diff --git a/src/dstr-assignment/array-elem-nested-obj-undefined-hole.case b/src/dstr-assignment/array-elem-nested-obj-undefined-hole.case
new file mode 100644
index 000000000..dc463ec81
--- /dev/null
+++ b/src/dstr-assignment/array-elem-nested-obj-undefined-hole.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When DestructuringAssignmentTarget is an object literal and the value is a
+ "hole", a TypeError should be thrown.
+template: error
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var x;
+//- error
+TypeError
+//- elems
+[{ x }]
+//- vals
+[ , ]
diff --git a/src/dstr-assignment/array-elem-nested-obj-undefined-own.case b/src/dstr-assignment/array-elem-nested-obj-undefined-own.case
new file mode 100644
index 000000000..179ae08e8
--- /dev/null
+++ b/src/dstr-assignment/array-elem-nested-obj-undefined-own.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When DestructuringAssignmentTarget is an object literal and the value is
+ `undefined`, a TypeError should be thrown.
+template: error
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var x;
+//- error
+TypeError
+//- elems
+[{ x }]
+//- vals
+[undefined]
diff --git a/src/dstr-assignment/array-elem-nested-obj-undefined.case b/src/dstr-assignment/array-elem-nested-obj-undefined.case
new file mode 100644
index 000000000..016d0590b
--- /dev/null
+++ b/src/dstr-assignment/array-elem-nested-obj-undefined.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When DestructuringAssignmentTarget is an object literal and no value is
+ defined, a TypeError should be thrown.
+template: error
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var x;
+//- error
+TypeError
+//- elems
+[{ x }]
+//- vals
+[]
diff --git a/src/dstr-assignment/array-elem-nested-obj-yield-expr.case b/src/dstr-assignment/array-elem-nested-obj-yield-expr.case
new file mode 100644
index 000000000..4622b03b7
--- /dev/null
+++ b/src/dstr-assignment/array-elem-nested-obj-yield-expr.case
@@ -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.
+
+/*---
+desc: >
+ When a `yield` token appears within the Initializer of a nested
+ destructuring assignment and within a generator function body, it behaves
+ as a YieldExpression.
+template: default
+es6id: 12.14.5.3
+features: [generators]
+---*/
+
+//- setup
+var iterationResult, iter, x;
+
+iter = (function*() {
+//- elems
+[{ x = yield }]
+//- vals
+[{}]
+//- teardown
+}());
+
+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);
diff --git a/src/dstr-assignment/array-elem-nested-obj-yield-ident-invalid.case b/src/dstr-assignment/array-elem-nested-obj-yield-ident-invalid.case
new file mode 100644
index 000000000..ce9db7641
--- /dev/null
+++ b/src/dstr-assignment/array-elem-nested-obj-yield-ident-invalid.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When a `yield` token appears within the Initializer of a nested
+ destructuring assignment outside of a generator function body, it behaves
+ as a IdentifierReference.
+template: syntax
+es6id: 12.14.5.3
+flags: [onlyStrict]
+negative: SyntaxError
+---*/
+
+//- elems
+[{ x = yield }]
+//- vals
+[{}]
diff --git a/src/dstr-assignment/array-elem-nested-obj-yield-ident-valid.case b/src/dstr-assignment/array-elem-nested-obj-yield-ident-valid.case
new file mode 100644
index 000000000..d0caa64d4
--- /dev/null
+++ b/src/dstr-assignment/array-elem-nested-obj-yield-ident-valid.case
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When a `yield` token appears within the Initializer of a nested
+ destructuring assignment outside of a generator function body, it behaves
+ as an IdentifierReference.
+template: default
+es6id: 12.14.5.3
+flags: [noStrict]
+---*/
+
+//- setup
+var yield = 2;
+var x;
+//- elems
+[{ x = yield }]
+//- vals
+[{}]
+//- body
+assert.sameValue(x, 2);
diff --git a/src/dstr-assignment/array-elem-nested-obj.case b/src/dstr-assignment/array-elem-nested-obj.case
new file mode 100644
index 000000000..bcb987760
--- /dev/null
+++ b/src/dstr-assignment/array-elem-nested-obj.case
@@ -0,0 +1,20 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When DestructuringAssignmentTarget is an object literal, it should be
+ parsed as a DestructuringAssignmentPattern and evaluated as a destructuring
+ assignment.
+template: default
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var x;
+//- elems
+[{ x }]
+//- vals
+[{ x: 2 }]
+//- body
+assert.sameValue(x, 2);
diff --git a/src/dstr-assignment/array-elem-put-const.case b/src/dstr-assignment/array-elem-put-const.case
new file mode 100644
index 000000000..cbd284178
--- /dev/null
+++ b/src/dstr-assignment/array-elem-put-const.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ The assignment target should obey `const` semantics.
+template: error
+es6id: 12.14.5.3
+features: [const]
+---*/
+
+//- setup
+const c = null;
+//- error
+TypeError
+//- elems
+[ c ]
+//- vals
+[1]
diff --git a/src/dstr-assignment/array-elem-put-let.case b/src/dstr-assignment/array-elem-put-let.case
new file mode 100644
index 000000000..54dbfb4c4
--- /dev/null
+++ b/src/dstr-assignment/array-elem-put-let.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ The assignment target should obey `let` semantics.
+template: error
+es6id: 12.14.5.3
+features: [let]
+---*/
+
+//- elems
+[ x ]
+//- vals
+[]
+//- error
+ReferenceError
+//- teardown
+let x;
diff --git a/src/dstr-assignment/array-elem-put-prop-ref-no-get.case b/src/dstr-assignment/array-elem-put-prop-ref-no-get.case
new file mode 100644
index 000000000..6763ca4fc
--- /dev/null
+++ b/src/dstr-assignment/array-elem-put-prop-ref-no-get.case
@@ -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.
+
+/*---
+desc: >
+ If the DestructuringAssignmentTarget of an AssignmentElement is a
+ PropertyReference, it should not be evaluated.
+template: default
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var x, setValue;
+x = {
+ get y() {
+ $ERROR('The property should not be accessed.');
+ },
+ set y(val) {
+ setValue = val;
+ }
+};
+//- elems
+[x.y]
+//- vals
+[23]
+//- body
+assert.sameValue(setValue, 23);
diff --git a/src/dstr-assignment/array-elem-put-prop-ref-user-err.case b/src/dstr-assignment/array-elem-put-prop-ref-user-err.case
new file mode 100644
index 000000000..4f4792b43
--- /dev/null
+++ b/src/dstr-assignment/array-elem-put-prop-ref-user-err.case
@@ -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.
+
+/*---
+desc: >
+ Any error raised as a result of setting the value should be forwarded to
+ the runtime.
+template: error
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var x = {
+ set y(val) {
+ throw new Test262Error();
+ }
+};
+//- error
+Test262Error
+//- elems
+[x.y]
+//- vals
+[23]
diff --git a/src/dstr-assignment/array-elem-put-prop-ref.case b/src/dstr-assignment/array-elem-put-prop-ref.case
new file mode 100644
index 000000000..983bcfc57
--- /dev/null
+++ b/src/dstr-assignment/array-elem-put-prop-ref.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ The DestructuringAssignmentTarget of an AssignmentElement may be a
+ PropertyReference.
+template: default
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var x = {};
+//- elems
+[x.y]
+//- vals
+[4]
+//- body
+assert.sameValue(x.y, 4);
diff --git a/src/dstr-assignment/array-elem-put-unresolvable-no-strict.case b/src/dstr-assignment/array-elem-put-unresolvable-no-strict.case
new file mode 100644
index 000000000..fe7be7c70
--- /dev/null
+++ b/src/dstr-assignment/array-elem-put-unresolvable-no-strict.case
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ Outside of strict mode, if the the assignment target is an unresolvable
+ reference, a new `var` binding should be created in the environment record.
+template: default
+es6id: 12.14.5.3
+flags: [noStrict]
+---*/
+
+//- setup
+{
+//- elems
+[ unresolvable ]
+//- vals
+[]
+//- teardown
+}
+
+assert.sameValue(unresolvable, undefined);
diff --git a/src/dstr-assignment/array-elem-put-unresolvable-strict.case b/src/dstr-assignment/array-elem-put-unresolvable-strict.case
new file mode 100644
index 000000000..98dbacc75
--- /dev/null
+++ b/src/dstr-assignment/array-elem-put-unresolvable-strict.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ In strict mode, if the the assignment target is an unresolvable reference,
+ a ReferenceError should be thrown.
+template: error
+es6id: 12.14.5.3
+flags: [onlyStrict]
+---*/
+
+//- error
+ReferenceError
+//- elems
+[ unresolvable ]
+//- vals
+[]
diff --git a/src/dstr-assignment/array-elem-target-identifier.case b/src/dstr-assignment/array-elem-target-identifier.case
new file mode 100644
index 000000000..c45bbc8ac
--- /dev/null
+++ b/src/dstr-assignment/array-elem-target-identifier.case
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ Identifiers that appear as the DestructuringAssignmentTarget in an
+ AssignmentElement should take on the iterated value corresponding to their
+ position in the ArrayAssignmentPattern.
+template: default
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var x, y, z;
+//- elems
+[x, y, z]
+//- vals
+[1, 2, 3]
+//- body
+assert.sameValue(x, 1);
+assert.sameValue(y, 2);
+assert.sameValue(z, 3);
diff --git a/src/dstr-assignment/array-elem-target-simple-no-strict.case b/src/dstr-assignment/array-elem-target-simple-no-strict.case
new file mode 100644
index 000000000..6c442211b
--- /dev/null
+++ b/src/dstr-assignment/array-elem-target-simple-no-strict.case
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ Identifiers that appear as the DestructuringAssignmentTarget in an
+ AssignmentElement should take on the iterated value corresponding to their
+ position in the ArrayAssignmentPattern.
+template: default
+es6id: 12.14.5.3
+flags: [noStrict]
+---*/
+
+//- setup
+var argument, eval;
+//- elems
+[arguments, eval]
+//- vals
+[2, 3]
+//- body
+assert.sameValue(arguments, 2);
+assert.sameValue(eval, 3);
diff --git a/src/dstr-assignment/array-elem-target-simple-strict.case b/src/dstr-assignment/array-elem-target-simple-strict.case
new file mode 100644
index 000000000..b9a8adf77
--- /dev/null
+++ b/src/dstr-assignment/array-elem-target-simple-strict.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ It is a Syntax Error if LeftHandSideExpression is neither an
+ ObjectLiteral nor an ArrayLiteral and
+ IsValidSimpleAssignmentTarget(LeftHandSideExpression) is
+ false.
+template: syntax
+es6id: 12.14.5.1
+flags: [onlyStrict]
+negative: SyntaxError
+---*/
+
+//- elems
+[arguments]
+//- vals
+[]
diff --git a/src/dstr-assignment/array-elem-target-yield-expr.case b/src/dstr-assignment/array-elem-target-yield-expr.case
new file mode 100644
index 000000000..316af932b
--- /dev/null
+++ b/src/dstr-assignment/array-elem-target-yield-expr.case
@@ -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.
+
+/*---
+desc: >
+ When a `yield` token appears within the DestructuringAssignmentTarget of an
+ AssignmentElement within a generator function body, it behaves as a
+ YieldExpression.
+template: default
+es6id: 12.14.5.4
+features: [generators]
+---*/
+
+//- setup
+var value = [33];
+var x = {};
+var iterationResult, iter;
+
+iter = (function*() {
+//- elems
+[ x[yield] ]
+//- vals
+[33]
+//- teardown
+}());
+
+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);
diff --git a/src/dstr-assignment/array-elem-target-yield-invalid.case b/src/dstr-assignment/array-elem-target-yield-invalid.case
new file mode 100644
index 000000000..0ff824706
--- /dev/null
+++ b/src/dstr-assignment/array-elem-target-yield-invalid.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When a `yield` token appears within the DestructuringAssignmentTarget of an
+ AssignmentElement and outside of a generator function body, it behaves as
+ an IdentifierReference.
+template: syntax
+es6id: 12.14.5.4
+flags: [onlyStrict]
+negative: SyntaxError
+---*/
+
+//- elems
+[ x[yield] ]
+//- vals
+[]
diff --git a/src/dstr-assignment/array-elem-target-yield-valid.case b/src/dstr-assignment/array-elem-target-yield-valid.case
new file mode 100644
index 000000000..8b3263fab
--- /dev/null
+++ b/src/dstr-assignment/array-elem-target-yield-valid.case
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When a `yield` token appears within the DestructuringAssignmentTarget of an
+ AssignmentElement outside of a generator function body, it behaves as an
+ IdentifierReference.
+template: default
+es6id: 12.14.5.4
+flags: [noStrict]
+---*/
+
+//- setup
+var yield = 'prop';
+var x = {};
+//- elems
+[ x[yield] ]
+//- vals
+[33]
+//- body
+assert.sameValue(x.prop, 33);
diff --git a/src/dstr-assignment/array-elem-trlg-iter-elision-iter-abpt.case b/src/dstr-assignment/array-elem-trlg-iter-elision-iter-abpt.case
new file mode 100644
index 000000000..999469551
--- /dev/null
+++ b/src/dstr-assignment/array-elem-trlg-iter-elision-iter-abpt.case
@@ -0,0 +1,57 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: Abrupt completion returned during evaluation of elision
+info: |
+ 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).
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+
+//- error
+Test262Error
+//- elems
+[ x , , ]
+//- vals
+iterable
+//- teardown
+assert.sameValue(nextCount, 2);
+assert.sameValue(returnCount, 0);
diff --git a/src/dstr-assignment/array-elem-trlg-iter-elision-iter-nrml-close-err.case b/src/dstr-assignment/array-elem-trlg-iter-elision-iter-nrml-close-err.case
new file mode 100644
index 000000000..554f0662f
--- /dev/null
+++ b/src/dstr-assignment/array-elem-trlg-iter-elision-iter-nrml-close-err.case
@@ -0,0 +1,53 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: Abrupt completion returned from IteratorClose
+info: |
+ 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).
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- error
+Test262Error
+//- elems
+[ x , , ]
+//- vals
+iterable
+//- teardown
+assert.sameValue(nextCount, 2);
+assert.sameValue(returnCount, 1);
diff --git a/src/dstr-assignment/array-elem-trlg-iter-elision-iter-nrml-close-null.case b/src/dstr-assignment/array-elem-trlg-iter-elision-iter-nrml-close-null.case
new file mode 100644
index 000000000..8b67b0f7b
--- /dev/null
+++ b/src/dstr-assignment/array-elem-trlg-iter-elision-iter-nrml-close-null.case
@@ -0,0 +1,57 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose throws a TypeError when `return` returns a non-Object value
+info: |
+ 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.
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- error
+TypeError
+//- elems
+[ x , , ]
+//- vals
+iterable
diff --git a/src/dstr-assignment/array-elem-trlg-iter-elision-iter-nrml-close-skip.case b/src/dstr-assignment/array-elem-trlg-iter-elision-iter-nrml-close-skip.case
new file mode 100644
index 000000000..537491d49
--- /dev/null
+++ b/src/dstr-assignment/array-elem-trlg-iter-elision-iter-nrml-close-skip.case
@@ -0,0 +1,49 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: IteratorClose not invoked when elision exhausts the iterator
+info: |
+ 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).
+features: [Symbol.iterator]
+template: default
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- elems
+[ x , , ]
+//- vals
+iterable
+//- body
+assert.sameValue(nextCount, 2);
+assert.sameValue(returnCount, 0);
diff --git a/src/dstr-assignment/array-elem-trlg-iter-elision-iter-nrml-close.case b/src/dstr-assignment/array-elem-trlg-iter-elision-iter-nrml-close.case
new file mode 100644
index 000000000..9c99e7d2b
--- /dev/null
+++ b/src/dstr-assignment/array-elem-trlg-iter-elision-iter-nrml-close.case
@@ -0,0 +1,64 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: IteratorClose invoked when elision does not exhaust the iterator
+info: |
+ 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, « »).
+ [...]
+features: [Symbol.iterator]
+template: default
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- elems
+[ x , , ]
+//- vals
+iterable
+//- body
+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');
diff --git a/src/dstr-assignment/array-elem-trlg-iter-get-err.case b/src/dstr-assignment/array-elem-trlg-iter-get-err.case
new file mode 100644
index 000000000..b47c3ae4b
--- /dev/null
+++ b/src/dstr-assignment/array-elem-trlg-iter-get-err.case
@@ -0,0 +1,28 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: Abrupt completion returned from GetIterator
+info: |
+ ArrayAssignmentPattern :
+ [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+ 1. Let iterator be GetIterator(value).
+ 2. ReturnIfAbrupt(iterator).
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+var iterable = {};
+iterable[Symbol.iterator] = function() {
+ throw new Test262Error();
+};
+var x;
+//- error
+Test262Error
+//- elems
+[ x , ]
+//- vals
+iterable
diff --git a/src/dstr-assignment/array-elem-trlg-iter-list-nrml-close-err.case b/src/dstr-assignment/array-elem-trlg-iter-list-nrml-close-err.case
new file mode 100644
index 000000000..c432ef033
--- /dev/null
+++ b/src/dstr-assignment/array-elem-trlg-iter-list-nrml-close-err.case
@@ -0,0 +1,53 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: Abrupt completion returned from IteratorClose
+info: |
+ 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).
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- error
+Test262Error
+//- elems
+[ x , ]
+//- vals
+iterable
+//- teardown
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 1);
diff --git a/src/dstr-assignment/array-elem-trlg-iter-list-nrml-close-null.case b/src/dstr-assignment/array-elem-trlg-iter-list-nrml-close-null.case
new file mode 100644
index 000000000..2f2bf8995
--- /dev/null
+++ b/src/dstr-assignment/array-elem-trlg-iter-list-nrml-close-null.case
@@ -0,0 +1,57 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose throws a TypeError when `return` returns a non-Object value
+info: |
+ 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.
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- error
+TypeError
+//- elems
+[ x , ]
+//- vals
+iterable
diff --git a/src/dstr-assignment/array-elem-trlg-iter-list-nrml-close-skip.case b/src/dstr-assignment/array-elem-trlg-iter-list-nrml-close-skip.case
new file mode 100644
index 000000000..6ecaf2ebc
--- /dev/null
+++ b/src/dstr-assignment/array-elem-trlg-iter-list-nrml-close-skip.case
@@ -0,0 +1,52 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is not invoked when evaluation of AssignmentElementList
+ exhausts the iterator
+info: |
+ 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).
+features: [Symbol.iterator]
+template: default
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- elems
+[ x , ]
+//- vals
+iterable
+//- body
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
diff --git a/src/dstr-assignment/array-elem-trlg-iter-list-nrml-close.case b/src/dstr-assignment/array-elem-trlg-iter-list-nrml-close.case
new file mode 100644
index 000000000..519f63baa
--- /dev/null
+++ b/src/dstr-assignment/array-elem-trlg-iter-list-nrml-close.case
@@ -0,0 +1,65 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is invoked when evaluation of AssignmentElementList completes
+ without exhausting the iterator
+info: |
+ 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, « »).
+ [...]
+features: [Symbol.iterator]
+template: default
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- elems
+[ x , ]
+//- vals
+iterable
+//- body
+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');
diff --git a/src/dstr-assignment/array-elem-trlg-iter-list-rtrn-close-err.case b/src/dstr-assignment/array-elem-trlg-iter-list-rtrn-close-err.case
new file mode 100644
index 000000000..628e827e4
--- /dev/null
+++ b/src/dstr-assignment/array-elem-trlg-iter-list-rtrn-close-err.case
@@ -0,0 +1,65 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is invoked when evaluation of AssignmentElementList returns
+ a "return" completion and the iterator has not been marked as "done"
+info: |
+ 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).
+features: [Symbol.iterator, generators]
+template: default
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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() {
+//- elems
+[ {}[yield] , ]
+//- vals
+iterable
+//- body
+unreachable += 1;
+//- teardown
+}
+
+iter = g();
+iter.next();
+assert.throws(Test262Error, function() {
+ iter.return();
+});
+
+assert.sameValue(returnCount, 1);
+assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
diff --git a/src/dstr-assignment/array-elem-trlg-iter-list-rtrn-close-null.case b/src/dstr-assignment/array-elem-trlg-iter-list-rtrn-close-null.case
new file mode 100644
index 000000000..8a807a315
--- /dev/null
+++ b/src/dstr-assignment/array-elem-trlg-iter-list-rtrn-close-null.case
@@ -0,0 +1,59 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose throws a TypeError when `return` returns a non-Object value
+info: |
+ 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.
+features: [Symbol.iterator, generators]
+template: default
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+var iterable = {};
+var iterator = {
+ return: function() {
+ return null;
+ }
+};
+var iter;
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+function* g() {
+//- elems
+ [ {}[yield] , ]
+//- vals
+iterable
+//- teardown
+}
+
+iter = g();
+iter.next();
+
+assert.throws(TypeError, function() {
+ iter.return();
+});
diff --git a/src/dstr-assignment/array-elem-trlg-iter-list-rtrn-close.case b/src/dstr-assignment/array-elem-trlg-iter-list-rtrn-close.case
new file mode 100644
index 000000000..c7c10a93c
--- /dev/null
+++ b/src/dstr-assignment/array-elem-trlg-iter-list-rtrn-close.case
@@ -0,0 +1,73 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is invoked when evaluation of AssignmentElementList returns
+ a "return" completion and the iterator has not been marked as "done"
+info: |
+ 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).
+features: [Symbol.iterator, generators]
+template: default
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+var returnCount = 0;
+var unreachable = 0;
+var thisValue = null;
+var args = null;
+var iterable = {};
+var iterator = {
+ return: function() {
+ returnCount += 1;
+ thisValue = this;
+ args = arguments;
+ return {};
+ }
+};
+var iter, result;
+
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+function* g() {
+//- elems
+[ {}[yield] , ]
+//- vals
+iterable
+//- body
+ unreachable += 1;
+//- teardown
+};
+
+iter = g();
+iter.next();
+result = iter.return(888);
+
+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');
diff --git a/src/dstr-assignment/array-elem-trlg-iter-list-thrw-close-err.case b/src/dstr-assignment/array-elem-trlg-iter-list-thrw-close-err.case
new file mode 100644
index 000000000..683b386b9
--- /dev/null
+++ b/src/dstr-assignment/array-elem-trlg-iter-list-thrw-close-err.case
@@ -0,0 +1,64 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is invoked when evaluation of AssignmentElementList returns
+ a "throw" completion and the iterator has not been marked as "done"
+info: |
+ 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).
+
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+
+//- error
+Test262Error
+//- elems
+[ {}[thrower()] , ]
+//- vals
+iterable
+//- teardown
+
+assert.sameValue(nextCount, 0);
+assert.sameValue(returnCount, 1);
diff --git a/src/dstr-assignment/array-elem-trlg-iter-list-thrw-close-skip.case b/src/dstr-assignment/array-elem-trlg-iter-list-thrw-close-skip.case
new file mode 100644
index 000000000..28d98902f
--- /dev/null
+++ b/src/dstr-assignment/array-elem-trlg-iter-list-thrw-close-skip.case
@@ -0,0 +1,54 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is not invoked when evaluation of AssignmentElementList
+ returns an abrupt completion and the iterator has been marked as "done"
+info: |
+ 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).
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+//- error
+Test262Error
+//- elems
+[ x , ]
+//- vals
+iterable
+//- teardown
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
diff --git a/src/dstr-assignment/array-elem-trlg-iter-list-thrw-close.case b/src/dstr-assignment/array-elem-trlg-iter-list-thrw-close.case
new file mode 100644
index 000000000..b55284f19
--- /dev/null
+++ b/src/dstr-assignment/array-elem-trlg-iter-list-thrw-close.case
@@ -0,0 +1,66 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is invoked when evaluation of AssignmentElementList returns
+ a "throw" completion and the iterator has not been marked as "done"
+info: |
+ 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, « »).
+ [...]
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- error
+Test262Error
+//- elems
+[ {}[thrower()] , ]
+//- vals
+iterable
+//- teardown
+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');
diff --git a/src/dstr-assignment/array-elem-trlg-iter-rest-nrml-close-skip.case b/src/dstr-assignment/array-elem-trlg-iter-rest-nrml-close-skip.case
new file mode 100644
index 000000000..549977422
--- /dev/null
+++ b/src/dstr-assignment/array-elem-trlg-iter-rest-nrml-close-skip.case
@@ -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.
+/*---
+desc: >
+ IteratorClose is not called when rest element evaluation has exhausted the
+ iterator
+info: |
+ 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).
+features: [Symbol.iterator]
+template: default
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- elems
+[ x , ...y ]
+//- vals
+iterable
+//- teardown
+assert.sameValue(nextCount, 2, 'nextCount');
+assert.sameValue(returnCount, 0, 'returnCount');
+assert.sameValue(x, 1, 'x');
+assert.sameValue(y.length, 0, 'y.length');
diff --git a/src/dstr-assignment/array-elem-trlg-iter-rest-rtrn-close-err.case b/src/dstr-assignment/array-elem-trlg-iter-rest-rtrn-close-err.case
new file mode 100644
index 000000000..e2635d742
--- /dev/null
+++ b/src/dstr-assignment/array-elem-trlg-iter-rest-rtrn-close-err.case
@@ -0,0 +1,74 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is called when AssignmentRestEvaluation produces a "return"
+ completion due to reference evaluation
+info: |
+ 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).
+features: [Symbol.iterator, generators]
+template: default
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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() {
+//- elems
+[ x , ...{}[yield] ]
+//- vals
+iterable
+//- body
+ unreachable += 1;
+//- teardown
+}
+
+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');
diff --git a/src/dstr-assignment/array-elem-trlg-iter-rest-rtrn-close-null.case b/src/dstr-assignment/array-elem-trlg-iter-rest-rtrn-close-null.case
new file mode 100644
index 000000000..d241f1480
--- /dev/null
+++ b/src/dstr-assignment/array-elem-trlg-iter-rest-rtrn-close-null.case
@@ -0,0 +1,66 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose throws a TypeError when `return` returns a non-Object value
+info: |
+ 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).
+features: [Symbol.iterator, generators]
+template: default
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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() {
+//- elems
+[ x , ...{}[yield] ]
+//- vals
+iterable
+//- teardown
+}
+
+iter = g();
+iter.next();
+
+assert.throws(TypeError, function() {
+ iter.return();
+});
+
+assert.sameValue(nextCount, 1);
diff --git a/src/dstr-assignment/array-elem-trlg-iter-rest-rtrn-close.case b/src/dstr-assignment/array-elem-trlg-iter-rest-rtrn-close.case
new file mode 100644
index 000000000..c573c53fa
--- /dev/null
+++ b/src/dstr-assignment/array-elem-trlg-iter-rest-rtrn-close.case
@@ -0,0 +1,80 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is called when AssignmentRestEvaluation produces a "return"
+ completion due to reference evaluation
+info: |
+ 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).
+features: [Symbol.iterator, generators]
+template: default
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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() {
+//- elems
+[ x , ...{}[yield] ]
+//- vals
+iterable
+//- body
+ unreachable += 1;
+//- teardown
+}
+
+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');
diff --git a/src/dstr-assignment/array-elem-trlg-iter-rest-thrw-close-err.case b/src/dstr-assignment/array-elem-trlg-iter-rest-thrw-close-err.case
new file mode 100644
index 000000000..79ae32edb
--- /dev/null
+++ b/src/dstr-assignment/array-elem-trlg-iter-rest-thrw-close-err.case
@@ -0,0 +1,64 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is called when AssignmentRestEvaluation produces a "throw"
+ completion due to reference evaluation
+info: |
+ 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)
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- error
+Test262Error
+//- elems
+[ x , ...{}[thrower()] ]
+//- vals
+iterable
+//- teardown
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 1);
diff --git a/src/dstr-assignment/array-elem-trlg-iter-rest-thrw-close-skip.case b/src/dstr-assignment/array-elem-trlg-iter-rest-thrw-close-skip.case
new file mode 100644
index 000000000..5d53e4871
--- /dev/null
+++ b/src/dstr-assignment/array-elem-trlg-iter-rest-thrw-close-skip.case
@@ -0,0 +1,55 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: Abrupt completion returned during iteration for rest element
+info: |
+ 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).
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- error
+Test262Error
+//- elems
+[ x , ...x ]
+//- vals
+iterable
+//- teardown
+assert.sameValue(nextCount, 2);
+assert.sameValue(returnCount, 0);
diff --git a/src/dstr-assignment/array-elem-trlg-iter-rest-thrw-close.case b/src/dstr-assignment/array-elem-trlg-iter-rest-thrw-close.case
new file mode 100644
index 000000000..190857944
--- /dev/null
+++ b/src/dstr-assignment/array-elem-trlg-iter-rest-thrw-close.case
@@ -0,0 +1,68 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is called when AssignmentRestEvaluation produces a "throw"
+ completion due to reference evaluation
+info: |
+ 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, « »).
+ [...]
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- error
+Test262Error
+//- elems
+[ x , ...{}[thrower()] ]
+//- vals
+iterable
+//- teardown
+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');
diff --git a/src/dstr-assignment/array-elision-iter-abpt.case b/src/dstr-assignment/array-elision-iter-abpt.case
new file mode 100644
index 000000000..3ae10f479
--- /dev/null
+++ b/src/dstr-assignment/array-elision-iter-abpt.case
@@ -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.
+/*---
+desc: >
+ IteratorClose is not called when iteration produces an abrupt completion
+info: |
+ ArrayAssignmentPattern : [ Elision ]
+
+ 1. Let iterator be GetIterator(value).
+ [...]
+ 5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+ [...]
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- error
+Test262Error
+//- elems
+[ , ]
+//- vals
+iterable
+//- teardown
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
diff --git a/src/dstr-assignment/array-elision-iter-get-err.case b/src/dstr-assignment/array-elision-iter-get-err.case
new file mode 100644
index 000000000..d623ab690
--- /dev/null
+++ b/src/dstr-assignment/array-elision-iter-get-err.case
@@ -0,0 +1,26 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: Abrupt completion returned from GetIterator
+info: |
+ ArrayAssignmentPattern : [ Elision ]
+
+ 1. Let iterator be GetIterator(value).
+ 2. ReturnIfAbrupt(iterator).
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+var iterable = {};
+iterable[Symbol.iterator] = function() {
+ throw new Test262Error();
+};
+//- error
+Test262Error
+//- elems
+[ , ]
+//- vals
+iterable
diff --git a/src/dstr-assignment/array-elision-iter-nrml-close-err.case b/src/dstr-assignment/array-elision-iter-nrml-close-err.case
new file mode 100644
index 000000000..e6ea53ee7
--- /dev/null
+++ b/src/dstr-assignment/array-elision-iter-nrml-close-err.case
@@ -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.
+/*---
+desc: >
+ Abrupt completion returned from IteratorClose
+info: |
+ ArrayAssignmentPattern : [ Elision ]
+
+ 1. Let iterator be GetIterator(value).
+ [...]
+ 5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+ 6. Return result.
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- error
+Test262Error
+//- elems
+[ , ]
+//- vals
+iterable
+//- teardown
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 1);
diff --git a/src/dstr-assignment/array-elision-iter-nrml-close-null.case b/src/dstr-assignment/array-elision-iter-nrml-close-null.case
new file mode 100644
index 000000000..e91c29fcf
--- /dev/null
+++ b/src/dstr-assignment/array-elision-iter-nrml-close-null.case
@@ -0,0 +1,51 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose throws a TypeError when `return` returns a non-Object value
+info: |
+ 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.
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- error
+TypeError
+//- elems
+[ , ]
+//- vals
+iterable
diff --git a/src/dstr-assignment/array-elision-iter-nrml-close-skip.case b/src/dstr-assignment/array-elision-iter-nrml-close-skip.case
new file mode 100644
index 000000000..17d7c97ba
--- /dev/null
+++ b/src/dstr-assignment/array-elision-iter-nrml-close-skip.case
@@ -0,0 +1,43 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is not called when iteration has exhausted the iterator
+info: |
+ ArrayAssignmentPattern : [ Elision ]
+
+ 1. Let iterator be GetIterator(value).
+ [...]
+ 5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+ result).
+ [...]
+features: [Symbol.iterator]
+template: default
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- elems
+[ , ]
+//- vals
+iterable
+//- body
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
diff --git a/src/dstr-assignment/array-elision-iter-nrml-close.case b/src/dstr-assignment/array-elision-iter-nrml-close.case
new file mode 100644
index 000000000..71c75a2d5
--- /dev/null
+++ b/src/dstr-assignment/array-elision-iter-nrml-close.case
@@ -0,0 +1,59 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is called when assignment evaluation has not exhausted the
+ iterator
+info: |
+ 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, « »).
+ [...]
+features: [Symbol.iterator]
+template: default
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- elems
+[ , ]
+//- vals
+iterable
+//- body
+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');
diff --git a/src/dstr-assignment/array-elision-val-array.case b/src/dstr-assignment/array-elision-val-array.case
new file mode 100644
index 000000000..70895eeef
--- /dev/null
+++ b/src/dstr-assignment/array-elision-val-array.case
@@ -0,0 +1,13 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ An ArrayAssignmentPattern containing only Elisions requires iterable values
+template: default
+es6id: 12.14.5.2
+---*/
+
+//- elems
+[,]
+//- vals
+[]
diff --git a/src/dstr-assignment/array-elision-val-bool.case b/src/dstr-assignment/array-elision-val-bool.case
new file mode 100644
index 000000000..e9cbc6dd0
--- /dev/null
+++ b/src/dstr-assignment/array-elision-val-bool.case
@@ -0,0 +1,16 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ An ArrayAssignmentPattern containing only Elisions requires iterable values
+ and throws for boolean values.
+template: error
+es6id: 12.14.5.2
+---*/
+
+//- error
+TypeError
+//- elems
+[,]
+//- vals
+true
diff --git a/src/dstr-assignment/array-elision-val-null.case b/src/dstr-assignment/array-elision-val-null.case
new file mode 100644
index 000000000..3f4b64446
--- /dev/null
+++ b/src/dstr-assignment/array-elision-val-null.case
@@ -0,0 +1,16 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ An ArrayAssignmentPattern containing only Elisions requires iterable values
+ and throws for `null`.
+template: error
+es6id: 12.14.5.2
+---*/
+
+//- error
+TypeError
+//- elems
+[,]
+//- vals
+null
diff --git a/src/dstr-assignment/array-elision-val-num.case b/src/dstr-assignment/array-elision-val-num.case
new file mode 100644
index 000000000..99f14215d
--- /dev/null
+++ b/src/dstr-assignment/array-elision-val-num.case
@@ -0,0 +1,16 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ An ArrayAssignmentPattern containing only Elisions requires iterable values
+ and throws for number values.
+template: error
+es6id: 12.14.5.2
+---*/
+
+//- error
+TypeError
+//- elems
+[,]
+//- vals
+1
diff --git a/src/dstr-assignment/array-elision-val-string.case b/src/dstr-assignment/array-elision-val-string.case
new file mode 100644
index 000000000..4072011b8
--- /dev/null
+++ b/src/dstr-assignment/array-elision-val-string.case
@@ -0,0 +1,13 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ An ArrayAssignmentPattern containing only Elisions requires iterable values
+template: default
+es6id: 12.14.5.2
+---*/
+
+//- elems
+[,]
+//- vals
+'string literal'
diff --git a/src/dstr-assignment/array-elision-val-symbol.case b/src/dstr-assignment/array-elision-val-symbol.case
new file mode 100644
index 000000000..7b80f19b8
--- /dev/null
+++ b/src/dstr-assignment/array-elision-val-symbol.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ An ArrayAssignmentPattern containing only Elisions requires iterable values
+ and throws for symbol values.
+template: error
+es6id: 12.14.5.2
+features: [Symbol]
+---*/
+
+//- setup
+var s = Symbol();
+//- error
+TypeError
+//- elems
+[,]
+//- vals
+s
diff --git a/src/dstr-assignment/array-elision-val-undef.case b/src/dstr-assignment/array-elision-val-undef.case
new file mode 100644
index 000000000..4c7bf69fc
--- /dev/null
+++ b/src/dstr-assignment/array-elision-val-undef.case
@@ -0,0 +1,16 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ An ArrayAssignmentPattern containing only Elisions requires iterable values
+ and throws for `undefined`.
+template: error
+es6id: 12.14.5.2
+---*/
+
+//- error
+TypeError
+//- elems
+[,]
+//- vals
+undefined
diff --git a/src/dstr-assignment/array-empty-iter-close-err.case b/src/dstr-assignment/array-empty-iter-close-err.case
new file mode 100644
index 000000000..8d33d030d
--- /dev/null
+++ b/src/dstr-assignment/array-empty-iter-close-err.case
@@ -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.
+/*---
+desc: Abrupt completion returned from IteratorClose
+info: |
+ ArrayAssignmentPattern : [ ]
+
+ 1. Let iterator be GetIterator(value).
+ 2. ReturnIfAbrupt(iterator).
+ 3. Return IteratorClose(iterator, NormalCompletion(empty)).
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- error
+Test262Error
+//- elems
+[]
+//- vals
+iterable
+//- teardown
+assert.sameValue(nextCount, 0);
+assert.sameValue(returnCount, 1);
diff --git a/src/dstr-assignment/array-empty-iter-close-null.case b/src/dstr-assignment/array-empty-iter-close-null.case
new file mode 100644
index 000000000..42cef194a
--- /dev/null
+++ b/src/dstr-assignment/array-empty-iter-close-null.case
@@ -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.
+/*---
+desc: >
+ IteratorClose throws a TypeError when `return` returns a non-Object value
+info: |
+ 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.
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+var iterable = {};
+var iterator = {
+ next: function() {
+ return { done: true };
+ },
+ return: function() {
+ return null;
+ }
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+//- error
+TypeError
+//- elems
+[]
+//- vals
+iterable
diff --git a/src/dstr-assignment/array-empty-iter-close.case b/src/dstr-assignment/array-empty-iter-close.case
new file mode 100644
index 000000000..abd0f5790
--- /dev/null
+++ b/src/dstr-assignment/array-empty-iter-close.case
@@ -0,0 +1,53 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: Iterator is closed without iterating
+info: |
+ 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, « »).
+ [...]
+features: [Symbol.iterator]
+template: default
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- elems
+[]
+//- vals
+iterable
+//- body
+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');
diff --git a/src/dstr-assignment/array-empty-iter-get-err.case b/src/dstr-assignment/array-empty-iter-get-err.case
new file mode 100644
index 000000000..2a66e18b8
--- /dev/null
+++ b/src/dstr-assignment/array-empty-iter-get-err.case
@@ -0,0 +1,26 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: Abrupt completion returned from GetIterator
+info: |
+ ArrayAssignmentPattern : [ ]
+
+ 1. Let iterator be GetIterator(value).
+ 2. ReturnIfAbrupt(iterator).
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+var iterable = {};
+iterable[Symbol.iterator] = function() {
+ throw new Test262Error();
+};
+//- error
+Test262Error
+//- elems
+[]
+//- vals
+iterable
diff --git a/src/dstr-assignment/array-empty-val-array.case b/src/dstr-assignment/array-empty-val-array.case
new file mode 100644
index 000000000..5820b7175
--- /dev/null
+++ b/src/dstr-assignment/array-empty-val-array.case
@@ -0,0 +1,15 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ An ArrayAssignmentPattern without an AssignmentElementList requires
+ iterable values.
+template: default
+es6id: 12.14.5.2
+---*/
+
+//- elems
+[]
+//- vals
+[]
diff --git a/src/dstr-assignment/array-empty-val-bool.case b/src/dstr-assignment/array-empty-val-bool.case
new file mode 100644
index 000000000..327085e16
--- /dev/null
+++ b/src/dstr-assignment/array-empty-val-bool.case
@@ -0,0 +1,17 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ An ArrayAssignmentPattern without an AssignmentElementList requires
+ iterable values and throws for boolean values
+template: error
+es6id: 12.14.5.2
+---*/
+
+//- error
+TypeError
+//- elems
+[]
+//- vals
+true
diff --git a/src/dstr-assignment/array-empty-val-null.case b/src/dstr-assignment/array-empty-val-null.case
new file mode 100644
index 000000000..d42b89aca
--- /dev/null
+++ b/src/dstr-assignment/array-empty-val-null.case
@@ -0,0 +1,17 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ An ArrayAssignmentPattern without an AssignmentElementList requires
+ iterable values and throws for `null`.
+template: error
+es6id: 12.14.5.2
+---*/
+
+//- error
+TypeError
+//- elems
+[]
+//- vals
+null
diff --git a/src/dstr-assignment/array-empty-val-num.case b/src/dstr-assignment/array-empty-val-num.case
new file mode 100644
index 000000000..8adbc6526
--- /dev/null
+++ b/src/dstr-assignment/array-empty-val-num.case
@@ -0,0 +1,17 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ An ArrayAssignmentPattern without an AssignmentElementList requires
+ iterable values and throws for number values.
+template: error
+es6id: 12.14.5.2
+---*/
+
+//- error
+TypeError
+//- elems
+[]
+//- vals
+1
diff --git a/src/dstr-assignment/array-empty-val-string.case b/src/dstr-assignment/array-empty-val-string.case
new file mode 100644
index 000000000..102c9c37a
--- /dev/null
+++ b/src/dstr-assignment/array-empty-val-string.case
@@ -0,0 +1,15 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ An ArrayAssignmentPattern without an AssignmentElementList requires
+ iterable values.
+template: default
+es6id: 12.14.5.2
+---*/
+
+//- elems
+[]
+//- vals
+'string literal'
diff --git a/src/dstr-assignment/array-empty-val-symbol.case b/src/dstr-assignment/array-empty-val-symbol.case
new file mode 100644
index 000000000..723fc7eed
--- /dev/null
+++ b/src/dstr-assignment/array-empty-val-symbol.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ An ArrayAssignmentPattern without an AssignmentElementList requires
+ iterable values and throws for Symbol values.
+template: error
+es6id: 12.14.5.2
+---*/
+
+//- setup
+var s = Symbol();
+//- error
+TypeError
+//- elems
+[]
+//- vals
+s
diff --git a/src/dstr-assignment/array-empty-val-undef.case b/src/dstr-assignment/array-empty-val-undef.case
new file mode 100644
index 000000000..b2af20431
--- /dev/null
+++ b/src/dstr-assignment/array-empty-val-undef.case
@@ -0,0 +1,17 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ An ArrayAssignmentPattern without an AssignmentElementList requires
+ iterable values and throws for `undefined`.
+template: error
+es6id: 12.14.5.2
+---*/
+
+//- error
+TypeError
+//- elems
+[]
+//- vals
+undefined
diff --git a/src/dstr-assignment/array-iteration.case b/src/dstr-assignment/array-iteration.case
new file mode 100644
index 000000000..be62fb272
--- /dev/null
+++ b/src/dstr-assignment/array-iteration.case
@@ -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.
+
+/*---
+desc: >
+ Value iteration only proceeds for the number of elements in the
+ ArrayAssignmentPattern.
+template: default
+es6id: 12.14.5.3
+features: [generators]
+---*/
+
+//- setup
+var count = 0;
+var g = function*() {
+ count += 1;
+ yield;
+ count += 1;
+ yield;
+ count += 1;
+}
+//- elems
+[,,]
+//- vals
+g()
+//- body
+assert.sameValue(count, 2);
diff --git a/src/dstr-assignment/array-rest-after-element.case b/src/dstr-assignment/array-rest-after-element.case
new file mode 100644
index 000000000..bb80557b0
--- /dev/null
+++ b/src/dstr-assignment/array-rest-after-element.case
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ An AssignmentRestElement following an AssignmentElement consumes all
+ remaining iterable values.
+template: default
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var x, y;
+//- elems
+[x, ...y]
+//- vals
+[1, 2, 3]
+//- body
+assert.sameValue(x, 1);
+assert.sameValue(y.length, 2);
+assert.sameValue(y[0], 2);
+assert.sameValue(y[1], 3);
diff --git a/src/dstr-assignment/array-rest-after-elision.case b/src/dstr-assignment/array-rest-after-elision.case
new file mode 100644
index 000000000..48d06d5e1
--- /dev/null
+++ b/src/dstr-assignment/array-rest-after-elision.case
@@ -0,0 +1,21 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ An AssignmentRestElement following an elision consumes all remaining
+ iterable values.
+template: default
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var x;
+//- elems
+[, ...x]
+//- vals
+[1, 2, 3]
+//- body
+assert.sameValue(x.length, 2);
+assert.sameValue(x[0], 2);
+assert.sameValue(x[1], 3);
diff --git a/src/dstr-assignment/array-rest-before-element.case b/src/dstr-assignment/array-rest-before-element.case
new file mode 100644
index 000000000..fda8d7721
--- /dev/null
+++ b/src/dstr-assignment/array-rest-before-element.case
@@ -0,0 +1,16 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ An AssignmentElement may not follow an AssignmentRestElement in an
+ AssignmentElementList.
+template: syntax
+es6id: 12.14.5
+negative: SyntaxError
+---*/
+
+//- elems
+[...x, y]
+//- vals
+[]
diff --git a/src/dstr-assignment/array-rest-before-elision.case b/src/dstr-assignment/array-rest-before-elision.case
new file mode 100644
index 000000000..501f9ac1e
--- /dev/null
+++ b/src/dstr-assignment/array-rest-before-elision.case
@@ -0,0 +1,16 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ An elision may not follow an AssignmentRestElement in an
+ AssignmentElementList.
+template: syntax
+es6id: 12.14.5
+negative: SyntaxError
+---*/
+
+//- elems
+[...x,]
+//- vals
+[]
diff --git a/src/dstr-assignment/array-rest-before-rest.case b/src/dstr-assignment/array-rest-before-rest.case
new file mode 100644
index 000000000..a86de5f45
--- /dev/null
+++ b/src/dstr-assignment/array-rest-before-rest.case
@@ -0,0 +1,16 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ An AssignmentRestElement may not follow another AssignmentRestElement in an
+ AssignmentElementList.
+template: syntax
+es6id: 12.14.5
+negative: SyntaxError
+---*/
+
+//- elems
+[...x, ...y]
+//- vals
+[]
diff --git a/src/dstr-assignment/array-rest-elision-invalid.case b/src/dstr-assignment/array-rest-elision-invalid.case
new file mode 100644
index 000000000..f002f7169
--- /dev/null
+++ b/src/dstr-assignment/array-rest-elision-invalid.case
@@ -0,0 +1,16 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ ArrayAssignmentPattern may not include elisions following an
+ AssignmentRestElement in a AssignmentElementList.
+template: syntax
+es6id: 12.14.5
+negative: SyntaxError
+---*/
+
+//- elems
+[...x,]
+//- vals
+[]
diff --git a/src/dstr-assignment/array-rest-elision-iter-abpt.case b/src/dstr-assignment/array-rest-elision-iter-abpt.case
new file mode 100644
index 000000000..a84bab56f
--- /dev/null
+++ b/src/dstr-assignment/array-rest-elision-iter-abpt.case
@@ -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.
+/*---
+desc: >
+ IteratorClose is not called when assignment evaluation produces an abrupt
+ completion
+info: |
+ 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).
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+//- error
+Test262Error
+//- elems
+[ , ...x]
+//- vals
+iterable
+//- teardown
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
diff --git a/src/dstr-assignment/array-rest-elision.case b/src/dstr-assignment/array-rest-elision.case
new file mode 100644
index 000000000..09a814007
--- /dev/null
+++ b/src/dstr-assignment/array-rest-elision.case
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ ArrayAssignmentPattern may include elisions at any position preceeding a
+ AssignmentRestElement in a AssignmentElementList.
+template: default
+es6id: 12.14.5
+---*/
+
+//- setup
+var x, y;
+//- elems
+[, , x, , ...y]
+//- vals
+[1, 2, 3, 4, 5, 6]
+//- body
+assert.sameValue(x, 3);
+assert.sameValue(y.length, 2);
+assert.sameValue(y[0], 5);
+assert.sameValue(y[1], 6);
diff --git a/src/dstr-assignment/array-rest-init.case b/src/dstr-assignment/array-rest-init.case
new file mode 100644
index 000000000..02c329e20
--- /dev/null
+++ b/src/dstr-assignment/array-rest-init.case
@@ -0,0 +1,17 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ The AssignmentRestElement does not support an initializer.
+template: syntax
+es6id: 12.14.5
+negative: SyntaxError
+---*/
+
+//- setup
+var x;
+//- elems
+[...x = 1]
+//- vals
+[]
diff --git a/src/dstr-assignment/array-rest-iter-get-err.case b/src/dstr-assignment/array-rest-iter-get-err.case
new file mode 100644
index 000000000..7693c779d
--- /dev/null
+++ b/src/dstr-assignment/array-rest-iter-get-err.case
@@ -0,0 +1,27 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: Abrupt completion returned from GetIterator
+info: |
+ ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+ 1. Let iterator be GetIterator(value).
+ 2. ReturnIfAbrupt(iterator).
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+var iterable = {};
+var x;
+iterable[Symbol.iterator] = function() {
+ throw new Test262Error();
+};
+//- error
+Test262Error
+//- elems
+[...x]
+//- vals
+iterable
diff --git a/src/dstr-assignment/array-rest-iter-nrml-close-skip.case b/src/dstr-assignment/array-rest-iter-nrml-close-skip.case
new file mode 100644
index 000000000..627731aa6
--- /dev/null
+++ b/src/dstr-assignment/array-rest-iter-nrml-close-skip.case
@@ -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.
+/*---
+desc: >
+ IteratorClose is not called when assignment evaluation has exhausted the
+ iterator
+info: |
+ 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.
+features: [Symbol.iterator]
+template: default
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- elems
+[ ...x ]
+//- vals
+iterable
+//- body
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
diff --git a/src/dstr-assignment/array-rest-iter-rtrn-close-err.case b/src/dstr-assignment/array-rest-iter-rtrn-close-err.case
new file mode 100644
index 000000000..aaeb47a8d
--- /dev/null
+++ b/src/dstr-assignment/array-rest-iter-rtrn-close-err.case
@@ -0,0 +1,70 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is called when reference evaluation produces a "return"
+ completion
+info: |
+ 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).
+features: [Symbol.iterator, generators]
+template: default
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+var returnCount = 0;
+var unreachable = 0;
+function ReturnError() {}
+var iterable = {};
+var iterator = {
+ return: function() {
+ returnCount += 1;
+
+ throw new Test262Error();
+ }
+};
+var iter;
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+function* g() {
+//- elems
+[...{}[yield]]
+//- vals
+iterable
+//- body
+unreachable += 1;
+//- teardown
+}
+
+iter = g();
+iter.next();
+assert.throws(Test262Error, function() {
+ iter.return();
+});
+
+assert.sameValue(returnCount, 1);
+assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
diff --git a/src/dstr-assignment/array-rest-iter-rtrn-close-null.case b/src/dstr-assignment/array-rest-iter-rtrn-close-null.case
new file mode 100644
index 000000000..f911aea3f
--- /dev/null
+++ b/src/dstr-assignment/array-rest-iter-rtrn-close-null.case
@@ -0,0 +1,66 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose throws a TypeError when `return` returns a non-Object value
+info: |
+ 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).
+features: [Symbol.iterator, generators]
+template: default
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+var iterable = {};
+var iterator = {
+ return: function() {
+ return null;
+ }
+};
+var iter;
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+function* g() {
+//- elems
+[...{}[yield]]
+//- vals
+iterable
+//- teardown
+}
+
+iter = g();
+iter.next();
+
+assert.throws(TypeError, function() {
+ iter.return();
+});
diff --git a/src/dstr-assignment/array-rest-iter-rtrn-close.case b/src/dstr-assignment/array-rest-iter-rtrn-close.case
new file mode 100644
index 000000000..35366c2aa
--- /dev/null
+++ b/src/dstr-assignment/array-rest-iter-rtrn-close.case
@@ -0,0 +1,81 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is called when reference evaluation produces a "return"
+ completion
+info: |
+ 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).
+features: [Symbol.iterator, generators]
+template: default
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+var returnCount = 0;
+var unreachable = 0;
+var thisValue = null;
+var args = null;
+var iterable = {};
+var iterator = {
+ return: function() {
+ returnCount += 1;
+ thisValue = this;
+ args = arguments;
+ return {};
+ }
+};
+var iter, result;
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+
+function* g() {
+//- elems
+[...{}[yield]]
+//- vals
+iterable
+//- body
+unreachable += 1;
+//- teardown
+}
+
+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');
diff --git a/src/dstr-assignment/array-rest-iter-thrw-close-err.case b/src/dstr-assignment/array-rest-iter-thrw-close-err.case
new file mode 100644
index 000000000..4c98fb20f
--- /dev/null
+++ b/src/dstr-assignment/array-rest-iter-thrw-close-err.case
@@ -0,0 +1,64 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is called when reference evaluation produces a "throw"
+ completion
+info: |
+ 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).
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+
+//- error
+Test262Error
+//- elems
+[...{}[thrower()]]
+//- vals
+iterable
+//- teardown
+assert.sameValue(nextCount, 0);
+assert.sameValue(returnCount, 1);
diff --git a/src/dstr-assignment/array-rest-iter-thrw-close-skip.case b/src/dstr-assignment/array-rest-iter-thrw-close-skip.case
new file mode 100644
index 000000000..d95493775
--- /dev/null
+++ b/src/dstr-assignment/array-rest-iter-thrw-close-skip.case
@@ -0,0 +1,45 @@
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is not called when iteration produces an abrupt completion
+info: |
+ 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).
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- error
+Test262Error
+//- elems
+[...x]
+//- vals
+iterable
+//- teardown
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
diff --git a/src/dstr-assignment/array-rest-iter-thrw-close.case b/src/dstr-assignment/array-rest-iter-thrw-close.case
new file mode 100644
index 000000000..3028c1afe
--- /dev/null
+++ b/src/dstr-assignment/array-rest-iter-thrw-close.case
@@ -0,0 +1,72 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is called when reference evaluation produces a "throw"
+ completion
+info: |
+ 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, « »).
+ [...]
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- error
+Test262Error
+//- elems
+[...{}[thrower()]]
+//- vals
+iterable
+//- teardown
+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');
diff --git a/src/dstr-assignment/array-rest-iteration.case b/src/dstr-assignment/array-rest-iteration.case
new file mode 100644
index 000000000..8f1a8d2d3
--- /dev/null
+++ b/src/dstr-assignment/array-rest-iteration.case
@@ -0,0 +1,28 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ In the presense of an AssignmentRestElement, value iteration exhausts the
+ iterable value;
+template: default
+es6id: 12.14.5.3
+features: [generators]
+---*/
+
+//- setup
+var count = 0;
+var g = function*() {
+ count += 1;
+ yield;
+ count += 1;
+ yield;
+ count += 1;
+}
+var x;
+//- elems
+[...x]
+//- vals
+g()
+//- body
+assert.sameValue(count, 3);
diff --git a/src/dstr-assignment/array-rest-lref-err.case b/src/dstr-assignment/array-rest-lref-err.case
new file mode 100644
index 000000000..56f471205
--- /dev/null
+++ b/src/dstr-assignment/array-rest-lref-err.case
@@ -0,0 +1,56 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is called when reference evaluation produces an abrupt
+ completion
+info: |
+ 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).
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- error
+Test262Error
+//- elems
+[...{}[thrower()]]
+//- vals
+iterable
+//- teardown
+assert.sameValue(nextCount, 0);
+assert.sameValue(returnCount, 1);
diff --git a/src/dstr-assignment/array-rest-lref.case b/src/dstr-assignment/array-rest-lref.case
new file mode 100644
index 000000000..b16315041
--- /dev/null
+++ b/src/dstr-assignment/array-rest-lref.case
@@ -0,0 +1,53 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: Reference is evaluated during assignment
+info: |
+ 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).
+ [...]
+features: [Symbol.iterator]
+template: default
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- elems
+[...obj['a' + 'b']]
+//- vals
+iterable
+//- body
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
+assert(!!obj.ab);
+assert.sameValue(obj.ab.length, 0);
diff --git a/src/dstr-assignment/array-rest-nested-array-invalid.case b/src/dstr-assignment/array-rest-nested-array-invalid.case
new file mode 100644
index 000000000..08eff54e2
--- /dev/null
+++ b/src/dstr-assignment/array-rest-nested-array-invalid.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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.
+template: syntax
+es6id: 12.14.5.1
+negative: SyntaxError
+---*/
+
+//- elems
+[...[(x, y)]]
+//- vals
+[[]]
diff --git a/src/dstr-assignment/array-rest-nested-array-iter-thrw-close-skip.case b/src/dstr-assignment/array-rest-nested-array-iter-thrw-close-skip.case
new file mode 100644
index 000000000..c56953980
--- /dev/null
+++ b/src/dstr-assignment/array-rest-nested-array-iter-thrw-close-skip.case
@@ -0,0 +1,59 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is not called when nested array pattern evaluation produces
+ an abrupt completion
+info: |
+ 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.
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- error
+Test262Error
+//- elems
+[...[...{}[thrower()]]]
+//- vals
+iterable
+//- teardown
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
diff --git a/src/dstr-assignment/array-rest-nested-array-null.case b/src/dstr-assignment/array-rest-nested-array-null.case
new file mode 100644
index 000000000..9b68c38f6
--- /dev/null
+++ b/src/dstr-assignment/array-rest-nested-array-null.case
@@ -0,0 +1,21 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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.
+template: default
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var x, y;
+//- elems
+[...[x, y]]
+//- vals
+[null]
+//- body
+assert.sameValue(x, null);
+assert.sameValue(y, undefined);
diff --git a/src/dstr-assignment/array-rest-nested-array-undefined-hole.case b/src/dstr-assignment/array-rest-nested-array-undefined-hole.case
new file mode 100644
index 000000000..0b4566e8b
--- /dev/null
+++ b/src/dstr-assignment/array-rest-nested-array-undefined-hole.case
@@ -0,0 +1,20 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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.
+template: default
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var x = null;
+//- elems
+[...[x]]
+//- vals
+[ , ]
+//- body
+assert.sameValue(x, undefined);
diff --git a/src/dstr-assignment/array-rest-nested-array-undefined-own.case b/src/dstr-assignment/array-rest-nested-array-undefined-own.case
new file mode 100644
index 000000000..5da0f9982
--- /dev/null
+++ b/src/dstr-assignment/array-rest-nested-array-undefined-own.case
@@ -0,0 +1,20 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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.
+template: default
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var x = null;
+//- elems
+[...[x]]
+//- vals
+[undefined]
+//- body
+assert.sameValue(x, undefined);
diff --git a/src/dstr-assignment/array-rest-nested-array-undefined.case b/src/dstr-assignment/array-rest-nested-array-undefined.case
new file mode 100644
index 000000000..b4662b2b4
--- /dev/null
+++ b/src/dstr-assignment/array-rest-nested-array-undefined.case
@@ -0,0 +1,20 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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.
+template: default
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var x = null;
+//- elems
+[...[x]]
+//- vals
+[]
+//- body
+assert.sameValue(x, undefined);
diff --git a/src/dstr-assignment/array-rest-nested-array-yield-expr.case b/src/dstr-assignment/array-rest-nested-array-yield-expr.case
new file mode 100644
index 000000000..75b97caf0
--- /dev/null
+++ b/src/dstr-assignment/array-rest-nested-array-yield-expr.case
@@ -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.
+
+/*---
+desc: >
+ 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.
+template: default
+es6id: 12.14.5.3
+features: [generators]
+---*/
+
+//- setup
+var value = [86];
+var x = {};
+var iterationResult, iter;
+
+iter = (function*() {
+//- elems
+[...[x[yield]]]
+//- vals
+[86]
+//- teardown
+}());
+
+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);
diff --git a/src/dstr-assignment/array-rest-nested-array-yield-ident-invalid.case b/src/dstr-assignment/array-rest-nested-array-yield-ident-invalid.case
new file mode 100644
index 000000000..995a7f9ff
--- /dev/null
+++ b/src/dstr-assignment/array-rest-nested-array-yield-ident-invalid.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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.
+template: syntax
+es6id: 12.14.5.3
+flags: [onlyStrict]
+negative: SyntaxError
+---*/
+
+//- elems
+[...[x[yield]]]
+//- vals
+[]
diff --git a/src/dstr-assignment/array-rest-nested-array-yield-ident-valid.case b/src/dstr-assignment/array-rest-nested-array-yield-ident-valid.case
new file mode 100644
index 000000000..fd5eff61d
--- /dev/null
+++ b/src/dstr-assignment/array-rest-nested-array-yield-ident-valid.case
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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.
+template: default
+es6id: 12.14.5.3
+flags: [noStrict]
+---*/
+
+//- setup
+var yield = 'prop';
+var x = {};
+//- elems
+[...[x[yield]]]
+//- vals
+[86]
+//- body
+assert.sameValue(x.prop, 86);
diff --git a/src/dstr-assignment/array-rest-nested-array.case b/src/dstr-assignment/array-rest-nested-array.case
new file mode 100644
index 000000000..7f6f6562a
--- /dev/null
+++ b/src/dstr-assignment/array-rest-nested-array.case
@@ -0,0 +1,20 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When DestructuringAssignmentTarget is an array literal, it should be parsed
+ parsed as a DestructuringAssignmentPattern and evaluated as a destructuring
+ assignment.
+template: default
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var x;
+//- elems
+[...[x]]
+//- vals
+[1, 2, 3]
+//- body
+assert.sameValue(x, 1);
diff --git a/src/dstr-assignment/array-rest-nested-obj-invalid.case b/src/dstr-assignment/array-rest-nested-obj-invalid.case
new file mode 100644
index 000000000..ee38be20e
--- /dev/null
+++ b/src/dstr-assignment/array-rest-nested-obj-invalid.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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.
+template: syntax
+es6id: 12.14.5.1
+negative: SyntaxError
+---*/
+
+//- elems
+[...{ get x() {} }]
+//- vals
+[[]]
diff --git a/src/dstr-assignment/array-rest-nested-obj-null.case b/src/dstr-assignment/array-rest-nested-obj-null.case
new file mode 100644
index 000000000..4c4eb45c2
--- /dev/null
+++ b/src/dstr-assignment/array-rest-nested-obj-null.case
@@ -0,0 +1,21 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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.
+template: default
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var x, length;
+//- elems
+[...{ 0: x, length }]
+//- vals
+[null]
+//- body
+assert.sameValue(x, null);
+assert.sameValue(length, 1);
diff --git a/src/dstr-assignment/array-rest-nested-obj-undefined-hole.case b/src/dstr-assignment/array-rest-nested-obj-undefined-hole.case
new file mode 100644
index 000000000..54b078e8c
--- /dev/null
+++ b/src/dstr-assignment/array-rest-nested-obj-undefined-hole.case
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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.
+template: default
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var x = null;
+var length;
+//- elems
+[...{ 0: x, length }]
+//- vals
+[ , ]
+//- body
+assert.sameValue(x, undefined);
+assert.sameValue(length, 1);
diff --git a/src/dstr-assignment/array-rest-nested-obj-undefined-own.case b/src/dstr-assignment/array-rest-nested-obj-undefined-own.case
new file mode 100644
index 000000000..2a6aa15f0
--- /dev/null
+++ b/src/dstr-assignment/array-rest-nested-obj-undefined-own.case
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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.
+template: default
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var x = null;
+var length;
+//- elems
+[...{ 0: x, length }]
+//- vals
+[undefined]
+//- body
+assert.sameValue(x, undefined);
+assert.sameValue(length, 1);
diff --git a/src/dstr-assignment/array-rest-nested-obj-undefined.case b/src/dstr-assignment/array-rest-nested-obj-undefined.case
new file mode 100644
index 000000000..200ab543d
--- /dev/null
+++ b/src/dstr-assignment/array-rest-nested-obj-undefined.case
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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.
+template: default
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var x = null;
+var length;
+//- elems
+[...{ 0: x, length }]
+//- vals
+[]
+//- body
+assert.sameValue(x, undefined);
+assert.sameValue(length, 0);
diff --git a/src/dstr-assignment/array-rest-nested-obj-yield-expr.case b/src/dstr-assignment/array-rest-nested-obj-yield-expr.case
new file mode 100644
index 000000000..c867b58cc
--- /dev/null
+++ b/src/dstr-assignment/array-rest-nested-obj-yield-expr.case
@@ -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.
+
+/*---
+desc: >
+ 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.
+template: default
+es6id: 12.14.5.3
+features: [generators]
+---*/
+
+//- setup
+var iterationResult, iter, x;
+
+iter = (function*() {
+//- elems
+[...{ x = yield }]
+//- vals
+[{}]
+//- teardown
+}());
+
+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);
diff --git a/src/dstr-assignment/array-rest-nested-obj-yield-ident-invalid.case b/src/dstr-assignment/array-rest-nested-obj-yield-ident-invalid.case
new file mode 100644
index 000000000..9759c626c
--- /dev/null
+++ b/src/dstr-assignment/array-rest-nested-obj-yield-ident-invalid.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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.
+template: syntax
+es6id: 12.14.5.3
+flags: [onlyStrict]
+negative: SyntaxError
+---*/
+
+//- elems
+[...{ x = yield }]
+//- vals
+[{}]
diff --git a/src/dstr-assignment/array-rest-nested-obj-yield-ident-valid.case b/src/dstr-assignment/array-rest-nested-obj-yield-ident-valid.case
new file mode 100644
index 000000000..2d67dd451
--- /dev/null
+++ b/src/dstr-assignment/array-rest-nested-obj-yield-ident-valid.case
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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.
+template: default
+es6id: 12.14.5.3
+flags: [noStrict]
+---*/
+
+//- setup
+var yield = 2;
+var x;
+//- elems
+[...{ x = yield }]
+//- vals
+[{}]
+//- body
+assert.sameValue(x, 2);
diff --git a/src/dstr-assignment/array-rest-nested-obj.case b/src/dstr-assignment/array-rest-nested-obj.case
new file mode 100644
index 000000000..f3ac3e7ab
--- /dev/null
+++ b/src/dstr-assignment/array-rest-nested-obj.case
@@ -0,0 +1,20 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When DestructuringAssignmentTarget is an object literal, it should be
+ parsed as a DestructuringAssignmentPattern and evaluated as a destructuring
+ assignment.
+template: default
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var x;
+//- elems
+[...{ 1: x }]
+//- vals
+[1, 2, 3]
+//- body
+assert.sameValue(x, 2);
diff --git a/src/dstr-assignment/array-rest-put-const.case b/src/dstr-assignment/array-rest-put-const.case
new file mode 100644
index 000000000..67eb6eda5
--- /dev/null
+++ b/src/dstr-assignment/array-rest-put-const.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ The assignment target should obey `const` semantics.
+template: error
+es6id: 12.14.5.3
+features: [const]
+---*/
+
+//- setup
+const c = null;
+//- error
+TypeError
+//- elems
+[ ...c ]
+//- vals
+[1]
diff --git a/src/dstr-assignment/array-rest-put-let.case b/src/dstr-assignment/array-rest-put-let.case
new file mode 100644
index 000000000..9cc0cff48
--- /dev/null
+++ b/src/dstr-assignment/array-rest-put-let.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ The assignment target should obey `let` semantics.
+template: error
+es6id: 12.14.5.3
+features: [let]
+---*/
+
+//- error
+ReferenceError
+//- elems
+[ ...x ]
+//- vals
+[]
+//- teardown
+let x;
diff --git a/src/dstr-assignment/array-rest-put-prop-ref-no-get.case b/src/dstr-assignment/array-rest-put-prop-ref-no-get.case
new file mode 100644
index 000000000..1adb2c2e0
--- /dev/null
+++ b/src/dstr-assignment/array-rest-put-prop-ref-no-get.case
@@ -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.
+
+/*---
+desc: >
+ If the DestructuringAssignmentTarget of an AssignmentElement is a
+ PropertyReference, it should not be evaluated.
+template: default
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var setValue;
+var x = {
+ get y() {
+ $ERROR('The property should not be accessed.');
+ },
+ set y(val) {
+ setValue = val;
+ }
+};
+//- elems
+[...x.y]
+//- vals
+[23, 45, 99]
+//- body
+assert.sameValue(setValue.length, 3);
+assert.sameValue(setValue[0], 23);
+assert.sameValue(setValue[1], 45);
+assert.sameValue(setValue[2], 99);
diff --git a/src/dstr-assignment/array-rest-put-prop-ref-user-err-iter-close-skip.case b/src/dstr-assignment/array-rest-put-prop-ref-user-err-iter-close-skip.case
new file mode 100644
index 000000000..b82be99fe
--- /dev/null
+++ b/src/dstr-assignment/array-rest-put-prop-ref-user-err-iter-close-skip.case
@@ -0,0 +1,62 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ IteratorClose is not called when value assignment produces an abrupt
+ completion.
+info: |
+ 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).
+features: [Symbol.iterator]
+template: error
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+//- setup
+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;
+};
+//- error
+Test262Error
+//- elems
+[...obj.poisoned]
+//- vals
+iterable
+//- teardown
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
diff --git a/src/dstr-assignment/array-rest-put-prop-ref-user-err.case b/src/dstr-assignment/array-rest-put-prop-ref-user-err.case
new file mode 100644
index 000000000..0f4cc41d6
--- /dev/null
+++ b/src/dstr-assignment/array-rest-put-prop-ref-user-err.case
@@ -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.
+
+/*---
+desc: >
+ Any error raised as a result of setting the value should be forwarded to
+ the runtime.
+template: error
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var x = {
+ set y(val) {
+ throw new Test262Error();
+ }
+};
+//- error
+Test262Error
+//- elems
+[...x.y]
+//- vals
+[23]
diff --git a/src/dstr-assignment/array-rest-put-prop-ref.case b/src/dstr-assignment/array-rest-put-prop-ref.case
new file mode 100644
index 000000000..fda1af6dc
--- /dev/null
+++ b/src/dstr-assignment/array-rest-put-prop-ref.case
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ The DestructuringAssignmentTarget of an AssignmentElement may be a
+ PropertyReference.
+template: default
+es6id: 12.14.5.3
+---*/
+
+//- setup
+var x = {};
+//- elems
+[...x.y]
+//- vals
+[4, 3, 2]
+//- body
+assert.sameValue(x.y.length, 3);
+assert.sameValue(x.y[0], 4);
+assert.sameValue(x.y[1], 3);
+assert.sameValue(x.y[2], 2);
diff --git a/src/dstr-assignment/array-rest-put-unresolvable-no-strict.case b/src/dstr-assignment/array-rest-put-unresolvable-no-strict.case
new file mode 100644
index 000000000..9c95a9b9d
--- /dev/null
+++ b/src/dstr-assignment/array-rest-put-unresolvable-no-strict.case
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ Outside of strict mode, if the the assignment target is an unresolvable
+ reference, a new `var` binding should be created in the environment record.
+template: default
+es6id: 12.14.5.3
+flags: [noStrict]
+---*/
+
+//- setup
+{
+//- elems
+[ ...unresolvable ]
+//- vals
+[]
+//- teardown
+}
+
+assert.sameValue(unresolvable.length, 0);
diff --git a/src/dstr-assignment/array-rest-put-unresolvable-strict.case b/src/dstr-assignment/array-rest-put-unresolvable-strict.case
new file mode 100644
index 000000000..52cc2305a
--- /dev/null
+++ b/src/dstr-assignment/array-rest-put-unresolvable-strict.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ In strict mode, if the the assignment target is an unresolvable reference,
+ a ReferenceError should be thrown.
+template: error
+es6id: 12.14.5.3
+flags: [onlyStrict]
+---*/
+
+//- error
+ReferenceError
+//- elems
+[ ...unresolvable ]
+//- vals
+[]
diff --git a/src/dstr-assignment/array-rest-yield-expr.case b/src/dstr-assignment/array-rest-yield-expr.case
new file mode 100644
index 000000000..533800254
--- /dev/null
+++ b/src/dstr-assignment/array-rest-yield-expr.case
@@ -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.
+
+/*---
+desc: >
+ 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.
+template: default
+es6id: 12.14.5
+features: [generators]
+---*/
+
+//- setup
+var x = {};
+var iterationResult, iter;
+
+iter = (function*() {
+//- elems
+[...x[yield]]
+//- vals
+[33, 44, 55]
+//- teardown
+}());
+
+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);
diff --git a/src/dstr-assignment/array-rest-yield-ident-invalid.case b/src/dstr-assignment/array-rest-yield-ident-invalid.case
new file mode 100644
index 000000000..d635a7c5a
--- /dev/null
+++ b/src/dstr-assignment/array-rest-yield-ident-invalid.case
@@ -0,0 +1,20 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When a `yield` token appears within the DestructuringAssignmentTarget of an
+ AssignmentRestElement and outside of a generator function body, it should
+ behave as an IdentifierReference.
+template: syntax
+es6id: 12.14.5
+flags: [onlyStrict]
+negative: SyntaxError
+---*/
+
+//- setup
+var x = {};
+//- elems
+[...x[yield]]
+//- vals
+[]
diff --git a/src/dstr-assignment/array-rest-yield-ident-valid.case b/src/dstr-assignment/array-rest-yield-ident-valid.case
new file mode 100644
index 000000000..8168c4e81
--- /dev/null
+++ b/src/dstr-assignment/array-rest-yield-ident-valid.case
@@ -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.
+
+/*---
+desc: >
+ When a `yield` token appears within the DestructuringAssignmentTarget of an
+ AssignmentRestElement and outside of a generator function body, it should
+ behave as an IdentifierReference.
+template: default
+es6id: 12.14.5
+flags: [noStrict]
+---*/
+
+//- setup
+var yield = 'prop';
+var x = {};
+//- elems
+[...x[yield]]
+//- vals
+[33, 44, 55]
+//- body
+assert.sameValue(x.prop.length, 3);
+assert.sameValue(x.prop[0], 33);
+assert.sameValue(x.prop[1], 44);
+assert.sameValue(x.prop[2], 55);
diff --git a/src/dstr-assignment/default/assignment-expr.template b/src/dstr-assignment/default/assignment-expr.template
new file mode 100644
index 000000000..17c6a0387
--- /dev/null
+++ b/src/dstr-assignment/default/assignment-expr.template
@@ -0,0 +1,27 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/expressions/assignment/dstr-
+name: >
+ AssignmentExpression
+esid: sec-variable-statement-runtime-semantics-evaluation
+es6id: 13.3.2.4
+features: [destructuring-binding]
+info: |
+ VariableDeclaration : BindingPattern Initializer
+
+ 1. Let rhs be the result of evaluating Initializer.
+ 2. Let rval be GetValue(rhs).
+ 3. ReturnIfAbrupt(rval).
+ 4. Return the result of performing BindingInitialization for
+ BindingPattern passing rval and undefined as arguments.
+---*/
+
+var result;
+var vals = /*{ vals }*/;
+
+result = /*{ elems }*/ = vals;
+
+/*{ body }*/
+
+assert.sameValue(result, vals);
diff --git a/src/dstr-assignment/default/for-of.template b/src/dstr-assignment/default/for-of.template
new file mode 100644
index 000000000..36446c0af
--- /dev/null
+++ b/src/dstr-assignment/default/for-of.template
@@ -0,0 +1,36 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/statements/for-of/dstr-
+name: >
+ For..of statement
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+es6id: 13.7.5.11
+features: [destructuring-binding]
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. 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 (/*{ elems }*/ of [/*{ vals }*/]) {
+ /*{ body }*/
+ counter += 1;
+}
+
+assert.sameValue(counter, 1);
diff --git a/src/dstr-assignment/error/assignment-expr.template b/src/dstr-assignment/error/assignment-expr.template
new file mode 100644
index 000000000..4d9ece375
--- /dev/null
+++ b/src/dstr-assignment/error/assignment-expr.template
@@ -0,0 +1,22 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/expressions/assignment/dstr-
+name: >
+ AssignmentExpression
+esid: sec-variable-statement-runtime-semantics-evaluation
+es6id: 13.3.2.4
+features: [destructuring-binding]
+info: |
+ VariableDeclaration : BindingPattern Initializer
+
+ 1. Let rhs be the result of evaluating Initializer.
+ 2. Let rval be GetValue(rhs).
+ 3. ReturnIfAbrupt(rval).
+ 4. Return the result of performing BindingInitialization for
+ BindingPattern passing rval and undefined as arguments.
+---*/
+
+assert.throws(/*{ error }*/, function() {
+ 0, /*{ elems }*/ = /*{ vals }*/;
+});
diff --git a/src/dstr-assignment/error/for-of.template b/src/dstr-assignment/error/for-of.template
new file mode 100644
index 000000000..8484d8713
--- /dev/null
+++ b/src/dstr-assignment/error/for-of.template
@@ -0,0 +1,38 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/statements/for-of/dstr-
+name: >
+ For..of statement
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+es6id: 13.7.5.11
+features: [destructuring-binding]
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. 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(/*{ error }*/, function() {
+ for (/*{ elems }*/ of [/*{ vals }*/]) {
+ counter += 1;
+ }
+ counter += 1;
+});
+
+assert.sameValue(counter, 0);
diff --git a/src/dstr-assignment/obj-empty-bool.case b/src/dstr-assignment/obj-empty-bool.case
new file mode 100644
index 000000000..5e10c238a
--- /dev/null
+++ b/src/dstr-assignment/obj-empty-bool.case
@@ -0,0 +1,15 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ An ObjectAssignmentPattern without an AssignmentPropertyList requires an
+ object-coercible value (boolean value)
+template: default
+es6id: 12.14.5.2
+---*/
+
+//- elems
+{}
+//- vals
+false
diff --git a/src/dstr-assignment/obj-empty-null.case b/src/dstr-assignment/obj-empty-null.case
new file mode 100644
index 000000000..0d0c6dd2e
--- /dev/null
+++ b/src/dstr-assignment/obj-empty-null.case
@@ -0,0 +1,17 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ An ObjectAssignmentPattern without an AssignmentPropertyList requires an
+ object-coercible value (null value)
+template: error
+es6id: 12.14.5.2
+---*/
+
+//- error
+TypeError
+//- elems
+{}
+//- vals
+null
diff --git a/src/dstr-assignment/obj-empty-num.case b/src/dstr-assignment/obj-empty-num.case
new file mode 100644
index 000000000..582044a4a
--- /dev/null
+++ b/src/dstr-assignment/obj-empty-num.case
@@ -0,0 +1,15 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ An ObjectAssignmentPattern without an AssignmentPropertyList requires an
+ object-coercible value (number value)
+template: default
+es6id: 12.14.5.2
+---*/
+
+//- elems
+{}
+//- vals
+0
diff --git a/src/dstr-assignment/obj-empty-obj.case b/src/dstr-assignment/obj-empty-obj.case
new file mode 100644
index 000000000..f4fae6148
--- /dev/null
+++ b/src/dstr-assignment/obj-empty-obj.case
@@ -0,0 +1,15 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ An ObjectAssignmentPattern without an AssignmentPropertyList requires an
+ object-coercible value (object value)
+template: default
+es6id: 12.14.5.2
+---*/
+
+//- elems
+{}
+//- vals
+{}
diff --git a/src/dstr-assignment/obj-empty-string.case b/src/dstr-assignment/obj-empty-string.case
new file mode 100644
index 000000000..97542fe7e
--- /dev/null
+++ b/src/dstr-assignment/obj-empty-string.case
@@ -0,0 +1,15 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ An ObjectAssignmentPattern without an AssignmentPropertyList requires an
+ object-coercible value (string value)
+template: default
+es6id: 12.14.5.2
+---*/
+
+//- elems
+{}
+//- vals
+''
diff --git a/src/dstr-assignment/obj-empty-symbol.case b/src/dstr-assignment/obj-empty-symbol.case
new file mode 100644
index 000000000..429758940
--- /dev/null
+++ b/src/dstr-assignment/obj-empty-symbol.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ An ObjectAssignmentPattern without an AssignmentPropertyList requires an
+ object-coercible value (symbol value)
+template: default
+es6id: 12.14.5.2
+features: [Symbol]
+---*/
+
+//- setup
+var s = Symbol();
+//- elems
+{}
+//- vals
+s
diff --git a/src/dstr-assignment/obj-empty-undef.case b/src/dstr-assignment/obj-empty-undef.case
new file mode 100644
index 000000000..7c35e66be
--- /dev/null
+++ b/src/dstr-assignment/obj-empty-undef.case
@@ -0,0 +1,17 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ An ObjectAssignmentPattern without an AssignmentPropertyList requires an
+ object-coercible value (undefined value)
+template: error
+es6id: 12.14.5.2
+---*/
+
+//- error
+TypeError
+//- elems
+{}
+//- vals
+undefined
diff --git a/src/dstr-assignment/obj-id-identifier-resolution-first.case b/src/dstr-assignment/obj-id-identifier-resolution-first.case
new file mode 100644
index 000000000..c4398ae47
--- /dev/null
+++ b/src/dstr-assignment/obj-id-identifier-resolution-first.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ Evaluation of DestructuringAssignmentTarget (first of many)
+template: default
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x = null;
+var y;
+//- elems
+{ x, y }
+//- vals
+{ x: 3 }
+//- body
+assert.sameValue(x, 3);
diff --git a/src/dstr-assignment/obj-id-identifier-resolution-last.case b/src/dstr-assignment/obj-id-identifier-resolution-last.case
new file mode 100644
index 000000000..0997e5411
--- /dev/null
+++ b/src/dstr-assignment/obj-id-identifier-resolution-last.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ Evaluation of DestructuringAssignmentTarget (last of many)
+template: default
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x = null;
+var w;
+//- elems
+{ w, x }
+//- vals
+{ x: 4 }
+//- body
+assert.sameValue(x, 4);
diff --git a/src/dstr-assignment/obj-id-identifier-resolution-lone.case b/src/dstr-assignment/obj-id-identifier-resolution-lone.case
new file mode 100644
index 000000000..80e684f05
--- /dev/null
+++ b/src/dstr-assignment/obj-id-identifier-resolution-lone.case
@@ -0,0 +1,17 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ Evaluation of DestructuringAssignmentTarget (lone identifier)
+template: default
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x = null;
+//- elems
+{ x, }
+//- vals
+{ x: 2 }
+//- body
+assert.sameValue(x, 2);
diff --git a/src/dstr-assignment/obj-id-identifier-resolution-middle.case b/src/dstr-assignment/obj-id-identifier-resolution-middle.case
new file mode 100644
index 000000000..8dece135d
--- /dev/null
+++ b/src/dstr-assignment/obj-id-identifier-resolution-middle.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ Evaluation of DestructuringAssignmentTarget (within many)
+template: default
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x = null;
+var w, y;
+//- elems
+{ w, x, y }
+//- vals
+{ x: 5 }
+//- body
+assert.sameValue(x, 5);
diff --git a/src/dstr-assignment/obj-id-identifier-resolution-trlng.case b/src/dstr-assignment/obj-id-identifier-resolution-trlng.case
new file mode 100644
index 000000000..ed959bbd9
--- /dev/null
+++ b/src/dstr-assignment/obj-id-identifier-resolution-trlng.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+ Evaluation of DestructuringAssignmentTarget (lone identifier with trailing
+ comma)
+template: default
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x = null;
+//- elems
+{ x }
+//- vals
+{ x: 1 }
+//- body
+assert.sameValue(x, 1);
diff --git a/src/dstr-assignment/obj-id-identifier-yield-expr.case b/src/dstr-assignment/obj-id-identifier-yield-expr.case
new file mode 100644
index 000000000..8dc18230f
--- /dev/null
+++ b/src/dstr-assignment/obj-id-identifier-yield-expr.case
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ yield is not a valid IdentifierReference in an AssignmentProperty within
+ generator function bodies.
+template: syntax
+es6id: 12.14.5
+flags: [noStrict]
+features: [generators]
+negative: SyntaxError
+---*/
+
+//- setup
+(function*() {
+//- elems
+{ yield }
+//- vals
+{}
+//- teardown
+});
diff --git a/src/dstr-assignment/obj-id-identifier-yield-ident-invalid.case b/src/dstr-assignment/obj-id-identifier-yield-ident-invalid.case
new file mode 100644
index 000000000..83c135da4
--- /dev/null
+++ b/src/dstr-assignment/obj-id-identifier-yield-ident-invalid.case
@@ -0,0 +1,17 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ yield is not a valid IdentifierReference in an AssignmentProperty within
+ strict mode code.
+template: syntax
+es6id: 12.14.5
+flags: [onlyStrict]
+negative: SyntaxError
+---*/
+
+//- elems
+{ yield }
+//- vals
+{}
diff --git a/src/dstr-assignment/obj-id-identifier-yield-ident-valid.case b/src/dstr-assignment/obj-id-identifier-yield-ident-valid.case
new file mode 100644
index 000000000..fb7ce1808
--- /dev/null
+++ b/src/dstr-assignment/obj-id-identifier-yield-ident-valid.case
@@ -0,0 +1,20 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ yield is a valid IdentifierReference in an AssignmentProperty outside of
+ strict mode and generator functions.
+template: default
+es6id: 12.14.5
+flags: [noStrict]
+---*/
+
+//- setup
+var yield;
+//- elems
+{ yield }
+//- vals
+{ yield: 3 }
+//- body
+assert.sameValue(yield, 3);
diff --git a/src/dstr-assignment/obj-id-init-assignment-missing.case b/src/dstr-assignment/obj-id-init-assignment-missing.case
new file mode 100644
index 000000000..7ef57ff0f
--- /dev/null
+++ b/src/dstr-assignment/obj-id-init-assignment-missing.case
@@ -0,0 +1,20 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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).
+template: default
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x;
+//- elems
+{ x = 1 }
+//- vals
+{}
+//- body
+assert.sameValue(x, 1);
diff --git a/src/dstr-assignment/obj-id-init-assignment-null.case b/src/dstr-assignment/obj-id-init-assignment-null.case
new file mode 100644
index 000000000..698a2377f
--- /dev/null
+++ b/src/dstr-assignment/obj-id-init-assignment-null.case
@@ -0,0 +1,20 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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).
+template: default
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x;
+//- elems
+{ x = 1 }
+//- vals
+{ x: null }
+//- body
+assert.sameValue(x, null);
diff --git a/src/dstr-assignment/obj-id-init-assignment-truthy.case b/src/dstr-assignment/obj-id-init-assignment-truthy.case
new file mode 100644
index 000000000..9ee34246c
--- /dev/null
+++ b/src/dstr-assignment/obj-id-init-assignment-truthy.case
@@ -0,0 +1,20 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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).
+template: default
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x;
+//- elems
+{ x = 1 }
+//- vals
+{ x: 2 }
+//- body
+assert.sameValue(x, 2);
diff --git a/src/dstr-assignment/obj-id-init-assignment-undef.case b/src/dstr-assignment/obj-id-init-assignment-undef.case
new file mode 100644
index 000000000..beb088f12
--- /dev/null
+++ b/src/dstr-assignment/obj-id-init-assignment-undef.case
@@ -0,0 +1,20 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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).
+template: default
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x;
+//- elems
+{ x = 1 }
+//- vals
+{ x: undefined }
+//- body
+assert.sameValue(x, 1);
diff --git a/src/dstr-assignment/obj-id-init-evaluation.case b/src/dstr-assignment/obj-id-init-evaluation.case
new file mode 100644
index 000000000..c5892ff53
--- /dev/null
+++ b/src/dstr-assignment/obj-id-init-evaluation.case
@@ -0,0 +1,21 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ The Initializer should only be evaluated if v is undefined.
+template: default
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var flag1 = false;
+var flag2 = false;
+var x, y;
+//- elems
+{ x = flag1 = true, y = flag2 = true }
+//- vals
+{ y: 1 }
+//- body
+assert.sameValue(flag1, true);
+assert.sameValue(flag2, false);
diff --git a/src/dstr-assignment/obj-id-init-fn-name-arrow.case b/src/dstr-assignment/obj-id-init-fn-name-arrow.case
new file mode 100644
index 000000000..ba923bacb
--- /dev/null
+++ b/src/dstr-assignment/obj-id-init-fn-name-arrow.case
@@ -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.
+
+/*---
+desc: Assignment of function `name` attribute (ArrowFunction)
+template: default
+es6id: 12.14.5.2
+info: >
+ 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).
+includes: [propertyHelper.js]
+---*/
+
+//- setup
+var arrow;
+//- elems
+{ arrow = () => {} }
+//- vals
+{}
+//- body
+assert.sameValue(arrow.name, 'arrow');
+verifyNotEnumerable(arrow, 'name');
+verifyNotWritable(arrow, 'name');
+verifyConfigurable(arrow, 'name');
diff --git a/src/dstr-assignment/obj-id-init-fn-name-class.case b/src/dstr-assignment/obj-id-init-fn-name-class.case
new file mode 100644
index 000000000..69598a675
--- /dev/null
+++ b/src/dstr-assignment/obj-id-init-fn-name-class.case
@@ -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.
+
+/*---
+desc: Assignment of function `name` attribute (ClassExpression)
+template: default
+es6id: 12.14.5.2
+info: >
+ 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).
+includes: [propertyHelper.js]
+features: [class]
+---*/
+
+//- setup
+var xCls, cls;
+//- elems
+{ xCls = class x {}, cls = class {} }
+//- vals
+{}
+//- body
+assert.notSameValue(xCls.name, 'xCls');
+
+assert.sameValue(cls.name, 'cls');
+verifyNotEnumerable(cls, 'name');
+verifyNotWritable(cls, 'name');
+verifyConfigurable(cls, 'name');
diff --git a/src/dstr-assignment/obj-id-init-fn-name-cover.case b/src/dstr-assignment/obj-id-init-fn-name-cover.case
new file mode 100644
index 000000000..b0d92b229
--- /dev/null
+++ b/src/dstr-assignment/obj-id-init-fn-name-cover.case
@@ -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.
+
+/*---
+desc: >
+ Assignment of function `name` attribute (CoverParenthesizedExpression)
+template: default
+es6id: 12.14.5.2
+info: >
+ 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).
+includes: [propertyHelper.js]
+---*/
+
+//- setup
+var xCover, cover;
+//- elems
+{ xCover = (0, function() {}), cover = (function() {}) }
+//- vals
+{}
+//- body
+assert.notSameValue(xCover.name, 'xCover');
+
+assert.sameValue(cover.name, 'cover');
+verifyNotEnumerable(cover, 'name');
+verifyNotWritable(cover, 'name');
+verifyConfigurable(cover, 'name');
diff --git a/src/dstr-assignment/obj-id-init-fn-name-fn.case b/src/dstr-assignment/obj-id-init-fn-name-fn.case
new file mode 100644
index 000000000..28729746a
--- /dev/null
+++ b/src/dstr-assignment/obj-id-init-fn-name-fn.case
@@ -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.
+
+/*---
+desc: Assignment of function `name` attribute (FunctionExpression)
+template: default
+es6id: 12.14.5.2
+info: >
+ 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).
+includes: [propertyHelper.js]
+---*/
+
+//- setup
+var xFn, fn;
+//- elems
+{ xFn = function x() {}, fn = function() {} }
+//- vals
+{}
+//- body
+assert.notSameValue(xFn.name, 'xFn');
+
+assert.sameValue(fn.name, 'fn');
+verifyNotEnumerable(fn, 'name');
+verifyNotWritable(fn, 'name');
+verifyConfigurable(fn, 'name');
diff --git a/src/dstr-assignment/obj-id-init-fn-name-gen.case b/src/dstr-assignment/obj-id-init-fn-name-gen.case
new file mode 100644
index 000000000..712672024
--- /dev/null
+++ b/src/dstr-assignment/obj-id-init-fn-name-gen.case
@@ -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.
+
+/*---
+desc: Assignment of function `name` attribute (GeneratorExpression)
+template: default
+es6id: 12.14.5.2
+info: >
+ 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).
+includes: [propertyHelper.js]
+features: [generators]
+---*/
+
+//- setup
+var xGen, gen;
+//- elems
+{ xGen = function* x() {}, gen = function*() {} }
+//- vals
+{}
+//- body
+assert.notSameValue(xGen.name, 'xGen');
+
+assert.sameValue(gen.name, 'gen');
+verifyNotEnumerable(gen, 'name');
+verifyNotWritable(gen, 'name');
+verifyConfigurable(gen, 'name');
diff --git a/src/dstr-assignment/obj-id-init-in.case b/src/dstr-assignment/obj-id-init-in.case
new file mode 100644
index 000000000..fd5f36c78
--- /dev/null
+++ b/src/dstr-assignment/obj-id-init-in.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ The Initializer in an AssignmentProperty may be an `in` expression.
+template: default
+es6id: 12.14.5
+---*/
+
+//- setup
+var prop;
+//- elems
+{ prop = 'x' in {} }
+//- vals
+{}
+//- body
+assert.sameValue(prop, false);
diff --git a/src/dstr-assignment/obj-id-init-let.case b/src/dstr-assignment/obj-id-init-let.case
new file mode 100644
index 000000000..8581905f1
--- /dev/null
+++ b/src/dstr-assignment/obj-id-init-let.case
@@ -0,0 +1,21 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ Value retrieval of Initializer obeys `let` semantics.
+template: error
+es6id: 12.14.5.4
+features: [let]
+---*/
+
+//- setup
+var x;
+//- error
+ReferenceError
+//- elems
+{ x = y }
+//- vals
+{}
+//- teardown
+let y;
diff --git a/src/dstr-assignment/obj-id-init-order.case b/src/dstr-assignment/obj-id-init-order.case
new file mode 100644
index 000000000..a65a56651
--- /dev/null
+++ b/src/dstr-assignment/obj-id-init-order.case
@@ -0,0 +1,21 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ Initializer values should be assigned in left-to-right order.
+template: default
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x = 0;
+var a, b;
+//- elems
+{ a = x += 1, b = x *= 2 }
+//- vals
+{}
+//- body
+assert.sameValue(a, 1);
+assert.sameValue(b, 2);
+assert.sameValue(x, 2);
diff --git a/src/dstr-assignment/obj-id-init-simple-no-strict.case b/src/dstr-assignment/obj-id-init-simple-no-strict.case
new file mode 100644
index 000000000..b44e5bd09
--- /dev/null
+++ b/src/dstr-assignment/obj-id-init-simple-no-strict.case
@@ -0,0 +1,20 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ Evaluation of DestructuringAssignmentTarget.
+template: default
+es6id: 12.14.5.4
+flags: [noStrict]
+---*/
+
+//- setup
+var eval, arguments;
+//- elems
+{ eval = 3, arguments = 4 }
+//- vals
+{}
+//- body
+assert.sameValue(eval, 3);
+assert.sameValue(arguments, 4);
diff --git a/src/dstr-assignment/obj-id-init-simple-strict.case b/src/dstr-assignment/obj-id-init-simple-strict.case
new file mode 100644
index 000000000..b2faabe69
--- /dev/null
+++ b/src/dstr-assignment/obj-id-init-simple-strict.case
@@ -0,0 +1,17 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ It is a Syntax Error if IsValidSimpleAssignmentTarget of
+ IdentifierReference is false.
+template: syntax
+es6id: 12.14.5.1
+flags: [onlyStrict]
+negative: SyntaxError
+---*/
+
+//- elems
+{ eval = 0 }
+//- vals
+{}
diff --git a/src/dstr-assignment/obj-id-init-yield-expr.case b/src/dstr-assignment/obj-id-init-yield-expr.case
new file mode 100644
index 000000000..38e44e7e7
--- /dev/null
+++ b/src/dstr-assignment/obj-id-init-yield-expr.case
@@ -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.
+
+/*---
+desc: >
+ When a `yield` token appears within the Initializer of an
+ AssignmentProperty and within a generator function body, it should behave
+ as a YieldExpression.
+template: default
+es6id: 12.14.5
+features: [generators]
+---*/
+
+//- setup
+var iterationResult, x, iter;
+
+iter = (function*() {
+//- elems
+{ x = yield }
+//- vals
+{}
+//- teardown
+}());
+
+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);
diff --git a/src/dstr-assignment/obj-id-init-yield-ident-invalid.case b/src/dstr-assignment/obj-id-init-yield-ident-invalid.case
new file mode 100644
index 000000000..3d8d12f93
--- /dev/null
+++ b/src/dstr-assignment/obj-id-init-yield-ident-invalid.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When a `yield` token appears within the Initializer of an
+ AssignmentProperty and outside of a generator function body, it should
+ behave as an IdentifierReference.
+template: syntax
+es6id: 12.14.5
+flags: [onlyStrict]
+negative: SyntaxError
+---*/
+
+//- elems
+{ x = yield }
+//- vals
+{}
diff --git a/src/dstr-assignment/obj-id-init-yield-ident-valid.case b/src/dstr-assignment/obj-id-init-yield-ident-valid.case
new file mode 100644
index 000000000..93c9bc6af
--- /dev/null
+++ b/src/dstr-assignment/obj-id-init-yield-ident-valid.case
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When a `yield` token appears within the Initializer of an
+ AssignmentProperty and outside of a generator function body, it should
+ behave as an IdentifierReference.
+template: default
+es6id: 12.14.5
+flags: [noStrict]
+---*/
+
+//- setup
+var yield = 3;
+var x;
+//- elems
+{ x = yield }
+//- vals
+{}
+//- body
+assert.sameValue(x, 3);
diff --git a/src/dstr-assignment/obj-id-put-const.case b/src/dstr-assignment/obj-id-put-const.case
new file mode 100644
index 000000000..a6905afde
--- /dev/null
+++ b/src/dstr-assignment/obj-id-put-const.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ The assignment target should obey `const` semantics.
+template: error
+es6id: 12.14.5.4
+features: [const]
+---*/
+
+//- setup
+const c = null;
+//- error
+TypeError
+//- elems
+{ c }
+//- vals
+{ c: 1 }
diff --git a/src/dstr-assignment/obj-id-put-let.case b/src/dstr-assignment/obj-id-put-let.case
new file mode 100644
index 000000000..751878afe
--- /dev/null
+++ b/src/dstr-assignment/obj-id-put-let.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ The assignment target should obey `let` semantics.
+template: error
+es6id: 12.14.5.4
+features: [let]
+---*/
+
+//- error
+ReferenceError
+//- elems
+{ x }
+//- vals
+{}
+//- teardown
+let x;
diff --git a/src/dstr-assignment/obj-id-put-unresolvable-no-strict.case b/src/dstr-assignment/obj-id-put-unresolvable-no-strict.case
new file mode 100644
index 000000000..250d500a5
--- /dev/null
+++ b/src/dstr-assignment/obj-id-put-unresolvable-no-strict.case
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ Outside of strict mode, if the the assignment target is an unresolvable
+ reference, a new `var` binding should be created in the environment record.
+template: default
+es6id: 12.14.5.4
+flags: [noStrict]
+---*/
+
+//- setup
+{
+//- elems
+{ unresolvable }
+//- vals
+{}
+//- teardown
+}
+
+assert.sameValue(unresolvable, undefined);
diff --git a/src/dstr-assignment/obj-id-put-unresolvable-strict.case b/src/dstr-assignment/obj-id-put-unresolvable-strict.case
new file mode 100644
index 000000000..6dd866725
--- /dev/null
+++ b/src/dstr-assignment/obj-id-put-unresolvable-strict.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ In strict mode, if the the assignment target is an unresolvable reference,
+ a ReferenceError should be thrown.
+template: error
+es6id: 12.14.5.4
+flags: [onlyStrict]
+---*/
+
+//- error
+ReferenceError
+//- elems
+{ unresolvable }
+//- vals
+{}
diff --git a/src/dstr-assignment/obj-id-simple-no-strict.case b/src/dstr-assignment/obj-id-simple-no-strict.case
new file mode 100644
index 000000000..a191f2253
--- /dev/null
+++ b/src/dstr-assignment/obj-id-simple-no-strict.case
@@ -0,0 +1,20 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ Evaluation of DestructuringAssignmentTarget.
+template: default
+es6id: 12.14.5.4
+flags: [noStrict]
+---*/
+
+//- setup
+var eval, arguments;
+//- elems
+{ eval, arguments }
+//- vals
+{ eval: 1, arguments: 2 }
+//- teardown
+assert.sameValue(eval, 1);
+assert.sameValue(arguments, 2);
diff --git a/src/dstr-assignment/obj-id-simple-strict.case b/src/dstr-assignment/obj-id-simple-strict.case
new file mode 100644
index 000000000..19e92bb62
--- /dev/null
+++ b/src/dstr-assignment/obj-id-simple-strict.case
@@ -0,0 +1,17 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ It is a Syntax Error if IsValidSimpleAssignmentTarget of
+ IdentifierReference is false.
+template: syntax
+es6id: 12.14.5.1
+flags: [onlyStrict]
+negative: SyntaxError
+---*/
+
+//- elems
+{ eval }
+//- vals
+{}
diff --git a/src/dstr-assignment/obj-prop-elem-init-assignment-missing.case b/src/dstr-assignment/obj-prop-elem-init-assignment-missing.case
new file mode 100644
index 000000000..36b99b38d
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-elem-init-assignment-missing.case
@@ -0,0 +1,20 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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)
+template: default
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x;
+//- elems
+{ y: x = 1 }
+//- vals
+{}
+//- body
+assert.sameValue(x, 1);
diff --git a/src/dstr-assignment/obj-prop-elem-init-assignment-null.case b/src/dstr-assignment/obj-prop-elem-init-assignment-null.case
new file mode 100644
index 000000000..aac88b6d0
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-elem-init-assignment-null.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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)
+template: default
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x;
+//- elems
+{ y: x = 1 }
+//- vals
+{ y: null }
+//- body
+assert.sameValue(x, null);
diff --git a/src/dstr-assignment/obj-prop-elem-init-assignment-truthy.case b/src/dstr-assignment/obj-prop-elem-init-assignment-truthy.case
new file mode 100644
index 000000000..668c0a0b6
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-elem-init-assignment-truthy.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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)
+template: default
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x;
+//- elems
+{ y: x = 1 }
+//- vals
+{ y: 2 }
+//- body
+assert.sameValue(x, 2);
diff --git a/src/dstr-assignment/obj-prop-elem-init-assignment-undef.case b/src/dstr-assignment/obj-prop-elem-init-assignment-undef.case
new file mode 100644
index 000000000..abf1f527b
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-elem-init-assignment-undef.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ If the Initializer is present and v is undefined, the Initializer should be
+ evaluated and the result assigned to the target reference (undefined value)
+template: default
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x;
+//- elems
+{ y: x = 1 }
+//- vals
+{ y: undefined }
+//- body
+assert.sameValue(x, 1);
diff --git a/src/dstr-assignment/obj-prop-elem-init-evaluation.case b/src/dstr-assignment/obj-prop-elem-init-evaluation.case
new file mode 100644
index 000000000..47430121d
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-elem-init-evaluation.case
@@ -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.
+
+/*---
+desc: >
+ The Initializer should only be evaluated if v is undefined.
+template: default
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var flag1 = false;
+var flag2 = false;
+var x, y;
+//- elems
+{ x: x = flag1 = true, y: y = flag2 = true }
+//- vals
+{ y: 1 }
+//- body
+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`');
diff --git a/src/dstr-assignment/obj-prop-elem-init-fn-name-arrow.case b/src/dstr-assignment/obj-prop-elem-init-fn-name-arrow.case
new file mode 100644
index 000000000..3cfff7b2a
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-elem-init-fn-name-arrow.case
@@ -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.
+
+/*---
+desc: Assignment of function `name` attribute (ArrowFunction)
+template: default
+es6id: 12.14.5.4
+info: >
+ 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)).
+includes: [propertyHelper.js]
+---*/
+
+//- setup
+var arrow;
+//- elems
+{ x: arrow = () => {} }
+//- vals
+{}
+//- body
+assert.sameValue(arrow.name, 'arrow');
+verifyNotEnumerable(arrow, 'name');
+verifyNotWritable(arrow, 'name');
+verifyConfigurable(arrow, 'name');
diff --git a/src/dstr-assignment/obj-prop-elem-init-fn-name-class.case b/src/dstr-assignment/obj-prop-elem-init-fn-name-class.case
new file mode 100644
index 000000000..565235861
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-elem-init-fn-name-class.case
@@ -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.
+
+/*---
+desc: Assignment of function `name` attribute (ClassExpression)
+template: default
+es6id: 12.14.5.4
+info: >
+ 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)).
+includes: [propertyHelper.js]
+features: [class]
+---*/
+
+//- setup
+var xCls, cls;
+//- elems
+{ x: xCls = class x {}, x: cls = class {} }
+//- vals
+{}
+//- body
+assert.notSameValue(xCls.name, 'xCls');
+
+assert.sameValue(cls.name, 'cls');
+verifyNotEnumerable(cls, 'name');
+verifyNotWritable(cls, 'name');
+verifyConfigurable(cls, 'name');
diff --git a/src/dstr-assignment/obj-prop-elem-init-fn-name-cover.case b/src/dstr-assignment/obj-prop-elem-init-fn-name-cover.case
new file mode 100644
index 000000000..6e6afc489
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-elem-init-fn-name-cover.case
@@ -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.
+
+/*---
+desc: >
+ Assignment of function `name` attribute (CoverParenthesizedExpression)
+template: default
+es6id: 12.14.5.4
+info: >
+ 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)).
+includes: [propertyHelper.js]
+---*/
+
+//- setup
+var xCover, cover;
+//- elems
+{ x: xCover = (0, function() {}), x: cover = (function() {}) }
+//- vals
+{}
+//- body
+assert.notSameValue(xCover.name, 'xCover');
+
+assert.sameValue(cover.name, 'cover');
+verifyNotEnumerable(cover, 'name');
+verifyNotWritable(cover, 'name');
+verifyConfigurable(cover, 'name');
diff --git a/src/dstr-assignment/obj-prop-elem-init-fn-name-fn.case b/src/dstr-assignment/obj-prop-elem-init-fn-name-fn.case
new file mode 100644
index 000000000..7a2290ac6
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-elem-init-fn-name-fn.case
@@ -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.
+
+/*---
+desc: Assignment of function `name` attribute (FunctionExpression)
+template: default
+es6id: 12.14.5.4
+info: >
+ 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)).
+includes: [propertyHelper.js]
+---*/
+
+//- setup
+var xFn, fn;
+//- elems
+{ x: xFn = function x() {}, x: fn = function() {} }
+//- vals
+{}
+//- body
+assert.notSameValue(xFn.name, 'xFn');
+
+assert.sameValue(fn.name, 'fn');
+verifyNotEnumerable(fn, 'name');
+verifyNotWritable(fn, 'name');
+verifyConfigurable(fn, 'name');
diff --git a/src/dstr-assignment/obj-prop-elem-init-fn-name-gen.case b/src/dstr-assignment/obj-prop-elem-init-fn-name-gen.case
new file mode 100644
index 000000000..292e8c615
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-elem-init-fn-name-gen.case
@@ -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.
+
+/*---
+desc: Assignment of function `name` attribute (GeneratorExpression)
+template: default
+es6id: 12.14.5.4
+info: >
+ 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)).
+includes: [propertyHelper.js]
+features: [generators]
+---*/
+
+//- setup
+var xGen, gen;
+//- elems
+{ x: xGen = function* x() {}, x: gen = function*() {} }
+//- vals
+{}
+//- body
+assert.notSameValue(xGen.name, 'xGen');
+
+assert.sameValue(gen.name, 'gen');
+verifyNotEnumerable(gen, 'name');
+verifyNotWritable(gen, 'name');
+verifyConfigurable(gen, 'name');
diff --git a/src/dstr-assignment/obj-prop-elem-init-in.case b/src/dstr-assignment/obj-prop-elem-init-in.case
new file mode 100644
index 000000000..c55ce6a82
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-elem-init-in.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ The Initializer in an AssignmentElement may be an `in` expression.
+template: default
+es6id: 12.14.5
+---*/
+
+//- setup
+var prop;
+//- elems
+{ x: prop = 'x' in {} }
+//- vals
+{}
+//- body
+assert.sameValue(prop, false);
diff --git a/src/dstr-assignment/obj-prop-elem-init-let.case b/src/dstr-assignment/obj-prop-elem-init-let.case
new file mode 100644
index 000000000..75186a9f5
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-elem-init-let.case
@@ -0,0 +1,21 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ Value retrieval of Initializer obeys `let` semantics.
+template: error
+es6id: 12.14.5.4
+features: [let]
+---*/
+
+//- setup
+var x;
+//- error
+ReferenceError
+//- elems
+{ x: x = y }
+//- vals
+{}
+//- teardown
+let y;
diff --git a/src/dstr-assignment/obj-prop-elem-init-yield-expr.case b/src/dstr-assignment/obj-prop-elem-init-yield-expr.case
new file mode 100644
index 000000000..9295443bc
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-elem-init-yield-expr.case
@@ -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.
+
+/*---
+desc: >
+ When a `yield` token appears within the Initializer of an AssignmentElement
+ and within a generator function body, it should behave as a
+ YieldExpression.
+template: default
+es6id: 12.14.5.4
+features: [generators]
+---*/
+
+//- setup
+var iterationResult, iter, x;
+iter = (function*() {
+//- elems
+{ x: x = yield }
+//- vals
+{}
+//- teardown
+}());
+
+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);
diff --git a/src/dstr-assignment/obj-prop-elem-init-yield-ident-invalid.case b/src/dstr-assignment/obj-prop-elem-init-yield-ident-invalid.case
new file mode 100644
index 000000000..9c127af0e
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-elem-init-yield-ident-invalid.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When a `yield` token appears within the Initializer of an AssignmentElement
+ and outside of a generator function body, it should behave as an
+ IdentifierReference.
+template: syntax
+es6id: 12.14.5.4
+flags: [onlyStrict]
+negative: SyntaxError
+---*/
+
+//- elems
+{ x: x = yield }
+//- vals
+{}
diff --git a/src/dstr-assignment/obj-prop-elem-init-yield-ident-valid.case b/src/dstr-assignment/obj-prop-elem-init-yield-ident-valid.case
new file mode 100644
index 000000000..6ebaf3718
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-elem-init-yield-ident-valid.case
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When a `yield` token appears within the Initializer of an AssignmentElement
+ and outside of a generator function body, it should behave as an
+ IdentifierReference.
+template: default
+es6id: 12.14.5.4
+flags: [noStrict]
+---*/
+
+//- setup
+var yield = 4;
+var x;
+//- elems
+{ x: x = yield }
+//- vals
+{}
+//- body
+assert.sameValue(x, 4);
diff --git a/src/dstr-assignment/obj-prop-elem-target-yield-expr.case b/src/dstr-assignment/obj-prop-elem-target-yield-expr.case
new file mode 100644
index 000000000..2cc4cc9e3
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-elem-target-yield-expr.case
@@ -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.
+
+/*---
+desc: >
+ When a `yield` token appears within the DestructuringAssignmentTarget of an
+ AssignmentElement and within a generator function body, it should behave as
+ a YieldExpression.
+template: default
+es6id: 12.14.5.4
+features: [generators]
+---*/
+
+//- setup
+var x = {};
+var iterationResult, iter;
+
+iter = (function*() {
+//- elems
+{ x: x[yield] }
+//- vals
+{ x: 23 }
+//- teardown
+}());
+
+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);
diff --git a/src/dstr-assignment/obj-prop-elem-target-yield-ident-invalid.case b/src/dstr-assignment/obj-prop-elem-target-yield-ident-invalid.case
new file mode 100644
index 000000000..75503db0e
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-elem-target-yield-ident-invalid.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When a `yield` token appears within the DestructuringAssignmentTarget of an
+ AssignmentElement and outside of a generator function body, it should
+ behave as an IdentifierReference.
+template: syntax
+es6id: 12.14.5.4
+flags: [onlyStrict]
+negative: SyntaxError
+---*/
+
+//- elems
+{ x: x[yield] }
+//- vals
+{}
diff --git a/src/dstr-assignment/obj-prop-elem-target-yield-ident-valid.case b/src/dstr-assignment/obj-prop-elem-target-yield-ident-valid.case
new file mode 100644
index 000000000..597769a9f
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-elem-target-yield-ident-valid.case
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When a `yield` token appears within the DestructuringAssignmentTarget of an
+ AssignmentElement and outside of a generator function body, it should
+ behave as an IdentifierReference.
+template: default
+es6id: 12.14.5.4
+flags: [noStrict]
+---*/
+
+//- setup
+var yield = 'prop';
+var x = {};
+//- elems
+{ x: x[yield] }
+//- vals
+{ x: 23 }
+//- body
+assert.sameValue(x.prop, 23);
diff --git a/src/dstr-assignment/obj-prop-identifier-resolution-first.case b/src/dstr-assignment/obj-prop-identifier-resolution-first.case
new file mode 100644
index 000000000..267b49e16
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-identifier-resolution-first.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ Evaluation of DestructuringAssignmentTarget (first of many).
+template: default
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x = null;
+var y;
+//- elems
+{ a: x, y }
+//- vals
+{ a: 3 }
+//- body
+assert.sameValue(x, 3);
diff --git a/src/dstr-assignment/obj-prop-identifier-resolution-last.case b/src/dstr-assignment/obj-prop-identifier-resolution-last.case
new file mode 100644
index 000000000..4209cdfbd
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-identifier-resolution-last.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ Evaluation of DestructuringAssignmentTarget (last of many).
+template: default
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x = null;
+var w;
+//- elems
+{ w, a: x }
+//- vals
+{ a: 4 }
+//- body
+assert.sameValue(x, 4);
diff --git a/src/dstr-assignment/obj-prop-identifier-resolution-lone.case b/src/dstr-assignment/obj-prop-identifier-resolution-lone.case
new file mode 100644
index 000000000..ba2142a3d
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-identifier-resolution-lone.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ Evaluation of DestructuringAssignmentTarget (lone element).
+template: default
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x = null;
+//- elems
+{ a: x }
+//- vals
+{ a: 1 }
+//- body
+assert.sameValue(x, 1);
diff --git a/src/dstr-assignment/obj-prop-identifier-resolution-middle.case b/src/dstr-assignment/obj-prop-identifier-resolution-middle.case
new file mode 100644
index 000000000..651969b1b
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-identifier-resolution-middle.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ Evaluation of DestructuringAssignmentTarget (within many).
+template: default
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x = null;
+var w, y;
+//- elems
+{ w, a: x, y }
+//- vals
+{ a: 5 }
+//- body
+assert.sameValue(x, 5);
diff --git a/src/dstr-assignment/obj-prop-identifier-resolution-trlng.case b/src/dstr-assignment/obj-prop-identifier-resolution-trlng.case
new file mode 100644
index 000000000..6cf90f42b
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-identifier-resolution-trlng.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ Evaluation of DestructuringAssignmentTarget (lone element with trailing
+ comma).
+template: default
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x = null;
+//- elems
+{ a: x, }
+//- vals
+{ a: 2 }
+//- body
+assert.sameValue(x, 2);
diff --git a/src/dstr-assignment/obj-prop-name-evaluation-error.case b/src/dstr-assignment/obj-prop-name-evaluation-error.case
new file mode 100644
index 000000000..16861461b
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-name-evaluation-error.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ Any error raised as a result of evaluating PropertyName should be forwarded
+ to the runtime.
+template: error
+es6id: 12.14.5.2
+---*/
+
+//- setup
+var a, x;
+//- error
+TypeError
+//- elems
+{ [a.b]: x }
+//- vals
+{}
diff --git a/src/dstr-assignment/obj-prop-name-evaluation.case b/src/dstr-assignment/obj-prop-name-evaluation.case
new file mode 100644
index 000000000..2316d6d09
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-name-evaluation.case
@@ -0,0 +1,20 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ PropertyName of an AssignmentProperty may be a ComputedPropertyName.
+template: default
+es6id: 12.14.5.2
+---*/
+
+//- setup
+var x, y, xy;
+//- elems
+{ ['x' + 'y']: x }
+//- vals
+{ x: 1, xy: 23, y: 2 }
+//- body
+assert.sameValue(x, 23);
+assert.sameValue(y, undefined);
+assert.sameValue(xy, undefined);
diff --git a/src/dstr-assignment/obj-prop-nested-array-invalid.case b/src/dstr-assignment/obj-prop-nested-array-invalid.case
new file mode 100644
index 000000000..b4321822d
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-nested-array-invalid.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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.
+template: syntax
+es6id: 12.14.5.1
+negative: SyntaxError
+---*/
+
+//- elems
+{ x: [(x, y)] }
+//- vals
+{ x: [] }
diff --git a/src/dstr-assignment/obj-prop-nested-array-null.case b/src/dstr-assignment/obj-prop-nested-array-null.case
new file mode 100644
index 000000000..e893e8aa0
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-nested-array-null.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When DestructuringAssignmentTarget is an array literal and the value is
+ `null`, a TypeError should be thrown.
+template: error
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x;
+//- error
+TypeError
+//- elems
+{ x: [ x ] }
+//- vals
+{ x: null }
diff --git a/src/dstr-assignment/obj-prop-nested-array-undefined-own.case b/src/dstr-assignment/obj-prop-nested-array-undefined-own.case
new file mode 100644
index 000000000..415c4d999
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-nested-array-undefined-own.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When DestructuringAssignmentTarget is an array literal and the value is
+ `undefined`, a TypeError should be thrown.
+template: error
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x;
+//- error
+TypeError
+//- elems
+{ x: [ x ] }
+//- vals
+{ x: undefined }
diff --git a/src/dstr-assignment/obj-prop-nested-array-undefined.case b/src/dstr-assignment/obj-prop-nested-array-undefined.case
new file mode 100644
index 000000000..1e4230ae5
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-nested-array-undefined.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When DestructuringAssignmentTarget is an array literal and the value is not
+ defined, a TypeError should be thrown.
+template: error
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x;
+//- error
+TypeError
+//- elems
+{ x: [ x ] }
+//- vals
+{}
diff --git a/src/dstr-assignment/obj-prop-nested-array-yield-expr.case b/src/dstr-assignment/obj-prop-nested-array-yield-expr.case
new file mode 100644
index 000000000..fba8a40ad
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-nested-array-yield-expr.case
@@ -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.
+
+/*---
+desc: >
+ 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.
+template: default
+es6id: 12.14.5.4
+features: [generators]
+---*/
+
+//- setup
+var iterationResult, iter, x;
+
+iter = (function*() {
+//- elems
+{ x: [x = yield] }
+//- vals
+{ x: [] }
+//- teardown
+}());
+
+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);
diff --git a/src/dstr-assignment/obj-prop-nested-array-yield-ident-invalid.case b/src/dstr-assignment/obj-prop-nested-array-yield-ident-invalid.case
new file mode 100644
index 000000000..addafc3b4
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-nested-array-yield-ident-invalid.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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.
+template: syntax
+es6id: 12.14.5.4
+flags: [onlyStrict]
+negative: SyntaxError
+---*/
+
+//- elems
+{ x: [x = yield] }
+//- vals
+{ x: [] }
diff --git a/src/dstr-assignment/obj-prop-nested-array-yield-ident-valid.case b/src/dstr-assignment/obj-prop-nested-array-yield-ident-valid.case
new file mode 100644
index 000000000..19b82bbe5
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-nested-array-yield-ident-valid.case
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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.
+template: default
+es6id: 12.14.5.4
+flags: [noStrict]
+---*/
+
+//- setup
+var yield = 22;
+var x;
+//- elems
+{ x: [x = yield] }
+//- vals
+{ x: [] }
+//- body
+assert.sameValue(x, 22);
diff --git a/src/dstr-assignment/obj-prop-nested-array.case b/src/dstr-assignment/obj-prop-nested-array.case
new file mode 100644
index 000000000..3aabe634c
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-nested-array.case
@@ -0,0 +1,20 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When DestructuringAssignmentTarget is an array literal, it should be parsed
+ parsed as a DestructuringAssignmentPattern and evaluated as a destructuring
+ assignment.
+template: default
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var y;
+//- elems
+{ x: [y] }
+//- vals
+{ x: [321] }
+//- body
+assert.sameValue(y, 321);
diff --git a/src/dstr-assignment/obj-prop-nested-obj-invalid.case b/src/dstr-assignment/obj-prop-nested-obj-invalid.case
new file mode 100644
index 000000000..9bf46e92c
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-nested-obj-invalid.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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.
+template: syntax
+es6id: 12.14.5.1
+negative: SyntaxError
+---*/
+
+//- elems
+{ x: { get x() {} } }
+//- vals
+{ x: {} }
diff --git a/src/dstr-assignment/obj-prop-nested-obj-null.case b/src/dstr-assignment/obj-prop-nested-obj-null.case
new file mode 100644
index 000000000..d0f88aad7
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-nested-obj-null.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When DestructuringAssignmentTarget is an object literal and the value is
+ `null`, a TypeError should be thrown.
+template: error
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x;
+//- error
+TypeError
+//- elems
+{ x: { x } }
+//- vals
+{ x: null }
diff --git a/src/dstr-assignment/obj-prop-nested-obj-undefined-own.case b/src/dstr-assignment/obj-prop-nested-obj-undefined-own.case
new file mode 100644
index 000000000..506879add
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-nested-obj-undefined-own.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When DestructuringAssignmentTarget is an object literal and the value is
+ `undefined`, a TypeError should be thrown.
+template: error
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x;
+//- error
+TypeError
+//- elems
+{ x: { x } }
+//- vals
+{ x: undefined }
diff --git a/src/dstr-assignment/obj-prop-nested-obj-undefined.case b/src/dstr-assignment/obj-prop-nested-obj-undefined.case
new file mode 100644
index 000000000..742d2d99d
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-nested-obj-undefined.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When DestructuringAssignmentTarget is an object literal and the value is
+ not defined, a TypeError should be thrown.
+template: error
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x;
+//- error
+TypeError
+//- elems
+{ x: { x } }
+//- vals
+{}
diff --git a/src/dstr-assignment/obj-prop-nested-obj-yield-expr.case b/src/dstr-assignment/obj-prop-nested-obj-yield-expr.case
new file mode 100644
index 000000000..34bb01f8c
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-nested-obj-yield-expr.case
@@ -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.
+
+/*---
+desc: >
+ 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.
+template: default
+es6id: 12.14.5.4
+features: [generators]
+---*/
+
+//- setup
+var iterationResult, iter, x = undefined;
+
+iter = (function*() {
+//- elems
+{ x: { x = yield } }
+//- vals
+{ x: {} }
+//- teardown
+}());
+
+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);
diff --git a/src/dstr-assignment/obj-prop-nested-obj-yield-ident-invalid.case b/src/dstr-assignment/obj-prop-nested-obj-yield-ident-invalid.case
new file mode 100644
index 000000000..c37458e46
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-nested-obj-yield-ident-invalid.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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.
+template: syntax
+es6id: 12.14.5.4
+flags: [onlyStrict]
+negative: SyntaxError
+---*/
+
+//- elems
+{ x: { x = yield } }
+//- vals
+{ x: {} }
diff --git a/src/dstr-assignment/obj-prop-nested-obj-yield-ident-valid.case b/src/dstr-assignment/obj-prop-nested-obj-yield-ident-valid.case
new file mode 100644
index 000000000..5e30d0cb2
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-nested-obj-yield-ident-valid.case
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ 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.
+template: default
+es6id: 12.14.5.4
+flags: [noStrict]
+---*/
+
+//- setup
+var yield = 2;
+var result, x;
+//- elems
+{ x: { x = yield } }
+//- vals
+{ x: {} }
+//- body
+assert.sameValue(x, 2);
diff --git a/src/dstr-assignment/obj-prop-nested-obj.case b/src/dstr-assignment/obj-prop-nested-obj.case
new file mode 100644
index 000000000..2391e49b3
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-nested-obj.case
@@ -0,0 +1,20 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ When DestructuringAssignmentTarget is an object literal, it should be
+ parsed as a DestructuringAssignmentPattern and evaluated as a destructuring
+ assignment.
+template: default
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var result, y;
+//- elems
+{ x: { y } }
+//- vals
+{ x: { y: 2 } }
+//- body
+assert.sameValue(y, 2);
diff --git a/src/dstr-assignment/obj-prop-put-const.case b/src/dstr-assignment/obj-prop-put-const.case
new file mode 100644
index 000000000..fd3476593
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-put-const.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ The assignment target should obey `const` semantics.
+template: error
+es6id: 12.14.5.4
+features: [const]
+---*/
+
+//- setup
+const c = 1;
+//- error
+TypeError
+//- elems
+{ a: c }
+//- vals
+{ a: 2 }
diff --git a/src/dstr-assignment/obj-prop-put-let.case b/src/dstr-assignment/obj-prop-put-let.case
new file mode 100644
index 000000000..358c9d005
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-put-let.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ The assignment target should obey `let` semantics.
+template: error
+es6id: 12.14.5.4
+features: [let]
+---*/
+
+//- error
+ReferenceError
+//- elems
+{ a: x }
+//- vals
+{}
+//- teardown
+let x;
diff --git a/src/dstr-assignment/obj-prop-put-order.case b/src/dstr-assignment/obj-prop-put-order.case
new file mode 100644
index 000000000..6f4ca4faf
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-put-order.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ The AssignmentElements in an AssignmentElementList are evaluated in left-
+ to-right order.
+template: default
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x;
+//- elems
+{ z: x, a: x }
+//- vals
+{ a: 2, z: 1 }
+//- body
+assert.sameValue(x, 2);
diff --git a/src/dstr-assignment/obj-prop-put-prop-ref-no-get.case b/src/dstr-assignment/obj-prop-put-prop-ref-no-get.case
new file mode 100644
index 000000000..2b5b83ec5
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-put-prop-ref-no-get.case
@@ -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.
+
+/*---
+desc: >
+ If the DestructuringAssignmentTarget of an AssignmentElement is a
+ PropertyReference, it should not be evaluated.
+template: default
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var setValue;
+var x = {
+ get y() {
+ $ERROR('The property should not be accessed.');
+ },
+ set y(val) {
+ setValue = val;
+ }
+};
+//- elems
+{ a: x.y }
+//- vals
+{ a: 23 }
+//- body
+assert.sameValue(setValue, 23);
diff --git a/src/dstr-assignment/obj-prop-put-prop-ref-user-err.case b/src/dstr-assignment/obj-prop-put-prop-ref-user-err.case
new file mode 100644
index 000000000..1e119134f
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-put-prop-ref-user-err.case
@@ -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.
+
+/*---
+desc: >
+ Any error raised as a result of setting the value should be forwarded to
+ the runtime.
+template: error
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x = {
+ set y(val) {
+ throw new Test262Error();
+ }
+};
+//- error
+Test262Error
+//- elems
+{ a: x.y }
+//- vals
+{ a: 23 }
diff --git a/src/dstr-assignment/obj-prop-put-prop-ref.case b/src/dstr-assignment/obj-prop-put-prop-ref.case
new file mode 100644
index 000000000..6a78d80ff
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-put-prop-ref.case
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ The DestructuringAssignmentTarget of an AssignmentElement may be a
+ PropertyReference.
+template: default
+es6id: 12.14.5.4
+---*/
+
+//- setup
+var x = {};
+//- elems
+{ xy: x.y }
+//- vals
+{ xy: 4 }
+//- body
+assert.sameValue(x.y, 4);
diff --git a/src/dstr-assignment/obj-prop-put-unresolvable-no-strict.case b/src/dstr-assignment/obj-prop-put-unresolvable-no-strict.case
new file mode 100644
index 000000000..c2dff5c90
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-put-unresolvable-no-strict.case
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ Outside of strict mode, if the the assignment target is an unresolvable
+ reference, a new `var` binding should be created in the environment record.
+template: default
+es6id: 12.14.5.4
+flags: [noStrict]
+---*/
+
+//- setup
+{
+//- elems
+{ x: unresolvable }
+//- vals
+{}
+//- teardown
+}
+
+assert.sameValue(unresolvable, undefined);
diff --git a/src/dstr-assignment/obj-prop-put-unresolvable-strict.case b/src/dstr-assignment/obj-prop-put-unresolvable-strict.case
new file mode 100644
index 000000000..52cbdd565
--- /dev/null
+++ b/src/dstr-assignment/obj-prop-put-unresolvable-strict.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+desc: >
+ In strict mode, if the the assignment target is an unresolvable reference,
+ a ReferenceError should be thrown.
+template: error
+es6id: 12.14.5.4
+flags: [onlyStrict]
+---*/
+
+//- error
+ReferenceError
+//- elems
+{ x: unresolvable }
+//- vals
+{}
diff --git a/src/dstr-assignment/syntax/assignment-expr.template b/src/dstr-assignment/syntax/assignment-expr.template
new file mode 100644
index 000000000..a93edd3e6
--- /dev/null
+++ b/src/dstr-assignment/syntax/assignment-expr.template
@@ -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.
+/*---
+path: language/expressions/assignment/dstr-
+name: >
+ AssignmentExpression
+esid: sec-variable-statement-runtime-semantics-evaluation
+es6id: 13.3.2.4
+features: [destructuring-binding]
+info: |
+ VariableDeclaration : BindingPattern Initializer
+
+ 1. Let rhs be the result of evaluating Initializer.
+ 2. Let rval be GetValue(rhs).
+ 3. ReturnIfAbrupt(rval).
+ 4. Return the result of performing BindingInitialization for
+ BindingPattern passing rval and undefined as arguments.
+---*/
+
+0, /*{ elems }*/ = /*{ vals }*/;
diff --git a/src/dstr-assignment/syntax/for-in.template b/src/dstr-assignment/syntax/for-in.template
new file mode 100644
index 000000000..279b31996
--- /dev/null
+++ b/src/dstr-assignment/syntax/for-in.template
@@ -0,0 +1,29 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/statements/for-in/dstr-
+name: >
+ For..in statement
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+es6id: 13.7.5.11
+features: [destructuring-binding]
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+
+for (/*{ elems }*/ in [/*{ vals }*/]) ;
diff --git a/src/dstr-assignment/syntax/for-of.template b/src/dstr-assignment/syntax/for-of.template
new file mode 100644
index 000000000..430550dd3
--- /dev/null
+++ b/src/dstr-assignment/syntax/for-of.template
@@ -0,0 +1,29 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/statements/for-of/dstr-
+name: >
+ For..of statement
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+es6id: 13.7.5.11
+features: [destructuring-binding]
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+
+for (/*{ elems }*/ of [/*{ vals }*/]) ;