diff --git a/test/language/statements/for-of/body-dstr-assign-error.js b/test/language/statements/for-of/body-dstr-assign-error.js
new file mode 100644
index 0000000000000000000000000000000000000000..4e063574c1186361fcfb55bdb0e93f5a107e3bdf
--- /dev/null
+++ b/test/language/statements/for-of/body-dstr-assign-error.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4.13 S5.i.i
+description: >
+    If the left-hand side requires a DestructuringAssignment operation and that
+    operation produces an error, the iterator should be closed and the error
+    forwarded to the runtime.
+features: [Symbol.iterator]
+---*/
+
+var callCount = 0;
+var iterationCount = 0;
+var iterable = {};
+var x = {
+  set attr(_) {
+    throw new Test262Error();
+  }
+};
+
+iterable[Symbol.iterator] = function() {
+  return {
+    next: function() {
+      return { done: false, value: [0] };
+    },
+    return: function() {
+      callCount += 1;
+    }
+  }
+};
+
+assert.throws(Test262Error, function() {
+  for ([x.attr] of iterable) {
+    iterationCount += 1;
+  }
+});
+
+assert.sameValue(iterationCount, 0, 'The loop body is not evaluated');
+assert.sameValue(callCount, 1, 'Iterator is closed');
diff --git a/test/language/statements/for-of/body-dstr-assign.js b/test/language/statements/for-of/body-dstr-assign.js
new file mode 100644
index 0000000000000000000000000000000000000000..0bb9007c7d6c8ce3f3bef1a54948401a5991b4a3
--- /dev/null
+++ b/test/language/statements/for-of/body-dstr-assign.js
@@ -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.
+/*---
+es6id: 13.6.4.13 S5.i.i
+description: >
+    The left-hand side may take the form of a DestructuringAssignment.
+---*/
+
+var iterationCount = 0;
+var x;
+
+for ([x] of [[0]]) {
+  assert.sameValue(x, 0);
+  iterationCount += 1;
+}
+
+assert.sameValue(iterationCount, 1);
diff --git a/test/language/statements/for-of/body-put-error.js b/test/language/statements/for-of/body-put-error.js
new file mode 100644
index 0000000000000000000000000000000000000000..dd339e7e02071097ecfe185a50224c988a259b6b
--- /dev/null
+++ b/test/language/statements/for-of/body-put-error.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4.13 S5.h.ii
+description: >
+    If the left-hand side is not a lexical binding and the assignment produces
+    an error, the iterator should be closed and the error forwarded to the
+    runtime.
+features: [Symbol.iterator]
+---*/
+
+var callCount = 0;
+var iterationCount = 0;
+var iterable = {};
+var x = {
+  set attr(_) {
+    throw new Test262Error();
+  }
+};
+
+iterable[Symbol.iterator] = function() {
+  return {
+    next: function() {
+      return { done: false, value: 0 };
+    },
+    return: function() {
+      callCount += 1;
+    }
+  }
+};
+
+assert.throws(Test262Error, function() {
+  for (x.attr of iterable) {
+    iterationCount += 1;
+  }
+});
+
+assert.sameValue(iterationCount, 0, 'The loop body is not evaluated');
+assert.sameValue(callCount, 1, 'Iterator is closed');
diff --git a/test/language/statements/for-of/generator-close-via-break.js b/test/language/statements/for-of/generator-close-via-break.js
new file mode 100644
index 0000000000000000000000000000000000000000..ca18fde77b04f427b3441acf5bdbd28fa07bd5d6
--- /dev/null
+++ b/test/language/statements/for-of/generator-close-via-break.js
@@ -0,0 +1,47 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4.13
+description: >
+    Generators should be closed via their `return` method when iteration is
+    interrupted via a `break` statement.
+features: [generators]
+---*/
+
+var startedCount = 0;
+var finallyCount = 0;
+var iterationCount = 0;
+function* values() {
+  startedCount += 1;
+  try {
+    yield;
+    $ERROR('This code is unreachable (within `try` block)');
+  } finally {
+    finallyCount += 1;
+  }
+  $ERROR('This code is unreachable (following `try` statement)');
+}
+var iterable = values();
+
+assert.sameValue(
+  startedCount, 0, 'Generator is initialized in suspended state'
+);
+
+for (var x of iterable) {
+  assert.sameValue(
+    startedCount, 1, 'Generator executes prior to first iteration'
+  );
+  assert.sameValue(
+    finallyCount, 0, 'Generator is paused during first iteration'
+  );
+  iterationCount += 1;
+  break;
+}
+
+assert.sameValue(
+  startedCount, 1, 'Generator does not restart following interruption'
+);
+assert.sameValue(iterationCount, 1, 'A single iteration occurs');
+assert.sameValue(
+  finallyCount, 1, 'Generator is closed after `break` statement'
+);
diff --git a/test/language/statements/for-of/generator-close-via-return.js b/test/language/statements/for-of/generator-close-via-return.js
new file mode 100644
index 0000000000000000000000000000000000000000..a5963fae59a78c3881662e2d4322b608e0aa20c6
--- /dev/null
+++ b/test/language/statements/for-of/generator-close-via-return.js
@@ -0,0 +1,49 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4.13
+description: >
+    Generators should be closed via their `return` method when iteration is
+    interrupted via a `return` statement.
+features: [generators]
+---*/
+
+var startedCount = 0;
+var finallyCount = 0;
+var iterationCount = 0;
+function* values() {
+  startedCount += 1;
+  try {
+    yield;
+    $ERROR('This code is unreachable (within `try` block)');
+  } finally {
+    finallyCount += 1;
+  }
+  $ERROR('This code is unreachable (following `try` statement)');
+}
+var iterable = values();
+
+assert.sameValue(
+  startedCount, 0, 'Generator is initialized in suspended state'
+);
+
+(function() {
+  for (var x of iterable) {
+    assert.sameValue(
+      startedCount, 1, 'Generator executes prior to first iteration'
+    );
+    assert.sameValue(
+      finallyCount, 0, 'Generator is paused during first iteration'
+    );
+    iterationCount += 1;
+    return;
+  }
+}());
+
+assert.sameValue(
+  startedCount, 1, 'Generator does not restart following interruption'
+);
+assert.sameValue(iterationCount, 1, 'A single iteration occurs');
+assert.sameValue(
+  finallyCount, 1, 'Generator is closed after `return` statement'
+);
diff --git a/test/language/statements/for-of/generator-close-via-throw.js b/test/language/statements/for-of/generator-close-via-throw.js
new file mode 100644
index 0000000000000000000000000000000000000000..bbdadaf19bb16259fffaa9196418be4dea72c438
--- /dev/null
+++ b/test/language/statements/for-of/generator-close-via-throw.js
@@ -0,0 +1,49 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4.13
+description: >
+    Generators should be closed via their `return` method when iteration is
+    interrupted via a `throw` statement.
+features: [generators]
+---*/
+
+var startedCount = 0;
+var finallyCount = 0;
+var iterationCount = 0;
+function* values() {
+  startedCount += 1;
+  try {
+    yield;
+    $ERROR('This code is unreachable (within `try` block)');
+  } finally {
+    finallyCount += 1;
+  }
+  $ERROR('This code is unreachable (following `try` statement)');
+}
+var iterable = values();
+
+assert.sameValue(
+  startedCount, 0, 'Generator is initialized in suspended state'
+);
+
+try {
+  for (var x of iterable) {
+    assert.sameValue(
+      startedCount, 1, 'Generator executes prior to first iteration'
+    );
+    assert.sameValue(
+      finallyCount, 0, 'Generator is paused during first iteration'
+    );
+    iterationCount += 1;
+    throw 0;
+  }
+} catch(err) {}
+
+assert.sameValue(
+  startedCount, 1, 'Generator does not restart following interruption'
+);
+assert.sameValue(iterationCount, 1, 'A single iteration occurs');
+assert.sameValue(
+  finallyCount, 1, 'Generator is closed after `throw` statement'
+);
diff --git a/test/language/statements/for-of/generator-next-error.js b/test/language/statements/for-of/generator-next-error.js
new file mode 100644
index 0000000000000000000000000000000000000000..d284c5c252f4b59114c11f4c3ea2e756d88b25b7
--- /dev/null
+++ b/test/language/statements/for-of/generator-next-error.js
@@ -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.
+/*---
+es6id: 13.6.4.13 S5.g
+description: >
+    If `nextResult` is an abrupt completion as per IteratorStep (ES6 7.4.5),
+    return the completion.
+features: [generators]
+---*/
+
+var iterable = (function*() {
+  throw new Test262Error();
+}());
+var iterationCount = 0;
+
+assert.throws(Test262Error, function() {
+  for (var x of iterable) {
+    iterationCount += 1;
+  }
+});
+
+assert.sameValue(iterationCount, 0, 'The loop body is not evaluated');
diff --git a/test/language/statements/for-of/generator.js b/test/language/statements/for-of/generator.js
index 68a27ec4c192ce4378a3a762fa019d354b6dfe88..0caaaee8a959e54c79e47eda7e35336923677d67 100644
--- a/test/language/statements/for-of/generator.js
+++ b/test/language/statements/for-of/generator.js
@@ -4,6 +4,7 @@
 es6id: 13.6.4.13
 description: >
     Generator function should return valid iterable objects.
+features: [generators]
 ---*/
 
 function* values() {
diff --git a/test/language/statements/for-of/generic-iterable.js b/test/language/statements/for-of/generic-iterable.js
index f1e6d978bea121b6c2d1a99c980d19c3e025554f..b862c336d6d4df03d372c46de3e19abc2f728631 100644
--- a/test/language/statements/for-of/generic-iterable.js
+++ b/test/language/statements/for-of/generic-iterable.js
@@ -4,6 +4,7 @@
 es6id: 13.6.4.13
 description: >
     Generic objects with `@@iterator` protocols should function as iterables.
+features: [Symbol.iterator]
 ---*/
 
 var iterable = {};
diff --git a/test/language/statements/for-of/iterator-as-proxy.js b/test/language/statements/for-of/iterator-as-proxy.js
index cfb318ee596c1d694fbe0a3439cde34d6d333220..181e963e659643c4dc59621c115f1470df0634ba 100644
--- a/test/language/statements/for-of/iterator-as-proxy.js
+++ b/test/language/statements/for-of/iterator-as-proxy.js
@@ -5,6 +5,7 @@ es6id: 13.6.4.13
 description: >
     Iterators that are implemented as proxies should behave identically to
     non-proxy versions.
+features: [Proxy, Symbol.iterator]
 ---*/
 
 var iterable = {};
diff --git a/test/language/statements/for-of/iterator-close-get-method-error.js b/test/language/statements/for-of/iterator-close-get-method-error.js
new file mode 100644
index 0000000000000000000000000000000000000000..cec2854534f07947b405fa0b4afb1af615745dff
--- /dev/null
+++ b/test/language/statements/for-of/iterator-close-get-method-error.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4.13
+description: >
+    If retrieving an iterator's `return` method generates an error while
+    closing the iterator, the error should be forwarded to the runtime.
+features: [Symbol.iterator]
+---*/
+
+var iterable = {};
+var iterationCount = 0;
+
+iterable[Symbol.iterator] = function() {
+  return {
+    next: function() {
+      return { done: false, value: null };
+    },
+    get return() {
+      throw new Test262Error();
+    }
+  };
+};
+
+assert.throws(Test262Error, function() {
+  for (var x of iterable) {
+    iterationCount += 1;
+    break;
+  }
+});
+
+assert.sameValue(iterationCount, 1, 'The loop body is evaluated');
diff --git a/test/language/statements/for-of/iterator-close-non-object.js b/test/language/statements/for-of/iterator-close-non-object.js
new file mode 100644
index 0000000000000000000000000000000000000000..5f53f43ede3555062f32b042f483bc669bb94789
--- /dev/null
+++ b/test/language/statements/for-of/iterator-close-non-object.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4.13
+description: >
+    If an iterator's `return` method returns a non-Object value, a TypeError
+    should be thrown.
+features: [Symbol.iterator]
+---*/
+
+var iterable = {};
+var iterationCount = 0;
+
+iterable[Symbol.iterator] = function() {
+  return {
+    next: function() {
+      return { done: false, value: null };
+    },
+    return: function() {
+      return 0;
+    }
+  };
+};
+
+assert.throws(TypeError, function() {
+  for (var x of iterable) {
+    iterationCount += 1;
+    break;
+  }
+});
+
+assert.sameValue(iterationCount, 1, 'The loop body is evaluated');
diff --git a/test/language/statements/for-of/iterator-close-via-break.js b/test/language/statements/for-of/iterator-close-via-break.js
new file mode 100644
index 0000000000000000000000000000000000000000..f78664f7613fe6d4d5b87e1db43454b4e7f16e53
--- /dev/null
+++ b/test/language/statements/for-of/iterator-close-via-break.js
@@ -0,0 +1,46 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4.13
+description: >
+    Iterators should be closed via their `return` method when iteration is
+    interrupted via a `break` statement.
+features: [Symbol.iterator]
+---*/
+
+var startedCount = 0;
+var returnCount = 0;
+var iterationCount = 0;
+var iterable = {};
+
+iterable[Symbol.iterator] = function() {
+  return {
+    next: function() {
+      startedCount += 1;
+      return { done: false, value: null };
+    },
+    return: function() {
+      returnCount += 1;
+      return {};
+    }
+  };
+};
+
+for (var x of iterable) {
+  assert.sameValue(
+    startedCount, 1, 'Value is retrieved'
+  );
+  assert.sameValue(
+    returnCount, 0, 'Iterator is not closed'
+  );
+  iterationCount += 1;
+  break;
+}
+
+assert.sameValue(
+  startedCount, 1, 'Iterator does not restart following interruption'
+);
+assert.sameValue(iterationCount, 1, 'A single iteration occurs');
+assert.sameValue(
+  returnCount, 1, 'Iterator is closed after `break` statement'
+);
diff --git a/test/language/statements/for-of/iterator-close-via-return.js b/test/language/statements/for-of/iterator-close-via-return.js
new file mode 100644
index 0000000000000000000000000000000000000000..5748c241972caf29f73dc6d0f76770f1d2937111
--- /dev/null
+++ b/test/language/statements/for-of/iterator-close-via-return.js
@@ -0,0 +1,48 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4.13
+description: >
+    Iterators should be closed via their `return` method when iteration is
+    interrupted via a `return` statement.
+features: [Symbol.iterator]
+---*/
+
+var startedCount = 0;
+var returnCount = 0;
+var iterationCount = 0;
+var iterable = {};
+
+iterable[Symbol.iterator] = function() {
+  return {
+    next: function() {
+      startedCount += 1;
+      return { done: false, value: null };
+    },
+    return: function() {
+      returnCount += 1;
+      return {};
+    }
+  };
+};
+
+(function() {
+  for (var x of iterable) {
+    assert.sameValue(
+      startedCount, 1, 'Value is retrieved'
+    );
+    assert.sameValue(
+      returnCount, 0, 'Iterator is not closed'
+    );
+    iterationCount += 1;
+    return;
+  }
+}());
+
+assert.sameValue(
+  startedCount, 1, 'Iterator does not restart following interruption'
+);
+assert.sameValue(iterationCount, 1, 'A single iteration occurs');
+assert.sameValue(
+  returnCount, 1, 'Iterator is closed after `return` statement'
+);
diff --git a/test/language/statements/for-of/iterator-close-via-throw.js b/test/language/statements/for-of/iterator-close-via-throw.js
new file mode 100644
index 0000000000000000000000000000000000000000..1245c940e15fd8f9bd7c34a5b1d1371d975e63d5
--- /dev/null
+++ b/test/language/statements/for-of/iterator-close-via-throw.js
@@ -0,0 +1,48 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4.13
+description: >
+    Iterators should be closed via their `return` method when iteration is
+    interrupted via a `throw` statement.
+features: [Symbol.iterator]
+---*/
+
+var startedCount = 0;
+var returnCount = 0;
+var iterationCount = 0;
+var iterable = {};
+
+iterable[Symbol.iterator] = function() {
+  return {
+    next: function() {
+      startedCount += 1;
+      return { done: false, value: null };
+    },
+    return: function() {
+      returnCount += 1;
+      return {};
+    }
+  };
+};
+
+try {
+  for (var x of iterable) {
+    assert.sameValue(
+      startedCount, 1, 'Value is retrieved'
+    );
+    assert.sameValue(
+      returnCount, 0, 'Iterator is not closed'
+    );
+    iterationCount += 1;
+    throw 0;
+  }
+} catch (err) {}
+
+assert.sameValue(
+  startedCount, 1, 'Iterator does not restart following interruption'
+);
+assert.sameValue(iterationCount, 1, 'A single iteration occurs');
+assert.sameValue(
+  returnCount, 1, 'Iterator is closed after `throw` statement'
+);
diff --git a/test/language/statements/for-of/iterator-next-error.js b/test/language/statements/for-of/iterator-next-error.js
new file mode 100644
index 0000000000000000000000000000000000000000..bcecc0bb4c583c93f7d0d20927f3456b06961391
--- /dev/null
+++ b/test/language/statements/for-of/iterator-next-error.js
@@ -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.
+/*---
+es6id: 13.6.4.13 S5.d
+description: >
+    If `nextResult` is an abrupt completion as per IteratorStep (ES6 7.4.5),
+    return the completion.
+features: [Symbol.iterator]
+---*/
+
+var iterable = {};
+var iterationCount = 0;
+
+iterable[Symbol.iterator] = function() {
+  return {
+    next: function() {
+      throw new Test262Error();
+    }
+  };
+};
+
+assert.throws(Test262Error, function() {
+  for (var x of iterable) {
+    iterationCount += 1;
+  }
+});
+
+assert.sameValue(iterationCount, 0, 'The loop body is not evaluated');
diff --git a/test/language/statements/for-of/iterator-next-reference.js b/test/language/statements/for-of/iterator-next-reference.js
index c661bd24b0114f84d59668b0c83ed8568e61ea99..3fd8ebad54ce5a01731bf59dafc2d8631e8009aa 100644
--- a/test/language/statements/for-of/iterator-next-reference.js
+++ b/test/language/statements/for-of/iterator-next-reference.js
@@ -5,6 +5,7 @@ es6id: 13.6.4.13 S5.c
 description: >
     The iterator's `next` method should be accessed with each iteration as per
     the `IteratorStep` abstract operation (7.4.5).
+features: [Symbol.iterator]
 ---*/
 
 var iterable = {};
diff --git a/test/language/statements/for-of/iterator-next-result-done-attr.js b/test/language/statements/for-of/iterator-next-result-done-attr.js
index 2ae62891b1cbb7c7a8b3f7c270cc2abfb7e84167..cc793dd9afc2bd9f5e3c8da1aa5ab10f6196eee1 100644
--- a/test/language/statements/for-of/iterator-next-result-done-attr.js
+++ b/test/language/statements/for-of/iterator-next-result-done-attr.js
@@ -5,6 +5,7 @@ es6id: 7.4.3
 description: >
     The `done` value of iteration result objects should be interpreted as
     incomplete as per `ToBoolean` (7.1.2).
+features: [Symbol.iterator]
 ---*/
 
 var iterable = {};
diff --git a/test/language/statements/for-of/iterator-next-result-type.js b/test/language/statements/for-of/iterator-next-result-type.js
index 6ef932c83f8fa01dee3c4fd17a8fe669eb313eca..1b27b856a64ac0da125e2446fbb63b9f9e5748f6 100644
--- a/test/language/statements/for-of/iterator-next-result-type.js
+++ b/test/language/statements/for-of/iterator-next-result-type.js
@@ -5,6 +5,7 @@ es6id: 13.6.4.13 S5.c
 description: >
     If Type(result) is not Object, throw a TypeError exception as per
     `IteratorNext` (7.4.2 S4)
+features: [Symbol.iterator]
 ---*/
 
 var iterable = {};
diff --git a/test/language/statements/for-of/iterator-next-result-value-attr-error.js b/test/language/statements/for-of/iterator-next-result-value-attr-error.js
new file mode 100644
index 0000000000000000000000000000000000000000..9344c5ec328e98d2ea6c103fb6770ad87e7d02c7
--- /dev/null
+++ b/test/language/statements/for-of/iterator-next-result-value-attr-error.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4.13 S5.g
+description: >
+    If `nextValue` is an abrupt completion as per IteratorValue (ES6 7.4.4),
+    return the completion.
+features: [Symbol.iterator]
+---*/
+
+var iterable = {};
+var iterationCount = 0;
+
+iterable[Symbol.iterator] = function() {
+  return {
+    next: function() {
+      return {
+        done: false,
+        get value() {
+          throw new Test262Error();
+        }
+      };
+    }
+  };
+};
+
+assert.throws(Test262Error, function() {
+  for (var x of iterable) {
+    iterationCount += 1;
+  }
+});
+
+assert.sameValue(iterationCount, 0, 'The loop body is not evaluated');
diff --git a/test/language/statements/for-of/iterator-next-result-value-attr.js b/test/language/statements/for-of/iterator-next-result-value-attr.js
index a0545c53f2c438853cd99d858aa6229669acc9c1..5448efed3531c1f0a3952222410125ebd9f6eb24 100644
--- a/test/language/statements/for-of/iterator-next-result-value-attr.js
+++ b/test/language/statements/for-of/iterator-next-result-value-attr.js
@@ -1,10 +1,11 @@
 // Copyright (C) 2013 the V8 project authors. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
-es6id: 13.6.4.13 S5.c
+es6id: 13.6.4.13 S5.f
 description: >
-    The `done` value of iteration result objects should be interpreted as
-    incomplete as per `ToBoolean` (7.1.2).
+    The `value` of iteration result objects should be retrieved using the Get
+    abstract operation.
+features: [Symbol.iterator]
 ---*/
 
 var iterable = {};