Upgrade V8 to 5.1.281.57  DO NOT MERGE

FPIIM-449

Change-Id: Id981b686b4d587ac31697662eb98bb34be42ad90
(cherry picked from commit 3b9bc31999c9787eb726ecdbfd5796bfdec32a18)
diff --git a/test/mjsunit/harmony/iterator-close.js b/test/mjsunit/harmony/iterator-close.js
index 94785de..09e0153 100644
--- a/test/mjsunit/harmony/iterator-close.js
+++ b/test/mjsunit/harmony/iterator-close.js
@@ -4,6 +4,7 @@
 
 // Flags: --harmony-iterator-close
 
+
 function* g() { yield 42; return 88 };
 
 
@@ -11,33 +12,86 @@
 {
   g.prototype.return = null;
 
+
+  assertEquals(undefined, (() => {
+    for (var x of g()) { break; }
+  })());
+
   assertEquals(undefined, (() => {
     for (let x of g()) { break; }
   })());
 
   assertEquals(undefined, (() => {
+    for (const x of g()) { break; }
+  })());
+
+  assertEquals(undefined, (() => {
     for (x of g()) { break; }
   })());
 
+
+  assertThrowsEquals(() => {
+    for (var x of g()) { throw 42; }
+  }, 42);
+
   assertThrowsEquals(() => {
     for (let x of g()) { throw 42; }
   }, 42);
 
   assertThrowsEquals(() => {
+    for (const x of g()) { throw 42; }
+  }, 42);
+
+  assertThrowsEquals(() => {
     for (x of g()) { throw 42; }
   }, 42);
 
+
+  assertEquals(42, (() => {
+    for (var x of g()) { return 42; }
+  })());
+
   assertEquals(42, (() => {
     for (let x of g()) { return 42; }
   })());
 
   assertEquals(42, (() => {
+    for (const x of g()) { return 42; }
+  })());
+
+  assertEquals(42, (() => {
     for (x of g()) { return 42; }
   })());
 
-  assertEquals(42, eval('for (let x of g()) { x; }'));
+
+  assertEquals(42, eval('for (var x of g()) { x; }'));
 
   assertEquals(42, eval('for (let x of g()) { x; }'));
+
+  assertEquals(42, eval('for (const x of g()) { x; }'));
+
+  assertEquals(42, eval('for (x of g()) { x; }'));
+
+
+  assertEquals(42, (() => {
+    var [x] = g(); return x;
+  })());
+
+  assertEquals(42, (() => {
+    let [x] = g(); return x;
+  })());
+
+  assertEquals(42, (() => {
+    const [x] = g(); return x;
+  })());
+
+  assertEquals(42, (() => {
+    [x] = g(); return x;
+  })());
+
+  assertEquals(42,
+    (([x]) => x)(g())
+  );
 }
 
 
@@ -45,33 +99,86 @@
 {
   g.prototype.return = 666;
 
+
+  assertThrows(() => {
+    for (var x of g()) { break; }
+  }, TypeError);
+
   assertThrows(() => {
     for (let x of g()) { break; }
   }, TypeError);
 
   assertThrows(() => {
+    for (const x of g()) { break; }
+  }, TypeError);
+
+  assertThrows(() => {
     for (x of g()) { break; }
   }, TypeError);
 
+
+  assertThrows(() => {
+    for (var x of g()) { throw 666; }
+  }, TypeError);
+
   assertThrows(() => {
     for (let x of g()) { throw 666; }
   }, TypeError);
 
   assertThrows(() => {
+    for (const x of g()) { throw 666; }
+  }, TypeError);
+
+  assertThrows(() => {
     for (x of g()) { throw 666; }
   }, TypeError);
 
+
+  assertThrows(() => {
+    for (var x of g()) { return 666; }
+  }, TypeError);
+
   assertThrows(() => {
     for (let x of g()) { return 666; }
   }, TypeError);
 
   assertThrows(() => {
+    for (const x of g()) { return 666; }
+  }, TypeError);
+
+  assertThrows(() => {
     for (x of g()) { return 666; }
   }, TypeError);
 
-  assertEquals(42, eval('for (let x of g()) { x; }'));
+
+  assertEquals(42, eval('for (var x of g()) { x; }'));
 
   assertEquals(42, eval('for (let x of g()) { x; }'));
+
+  assertEquals(42, eval('for (const x of g()) { x; }'));
+
+  assertEquals(42, eval('for (x of g()) { x; }'));
+
+
+  assertThrows(() => {
+    var [x] = g(); return x;
+  }, TypeError);
+
+  assertThrows(() => {
+    let [x] = g(); return x;
+  }, TypeError);
+
+  assertThrows(() => {
+    const [x] = g(); return x;
+  }, TypeError);
+
+  assertThrows(() => {
+    [x] = g(); return x;
+  }, TypeError);
+
+  assertThrows(() => {
+    (([x]) => x)(g());
+  }, TypeError);
 }
 
 
@@ -79,20 +186,46 @@
 {
   g.prototype.return = () => 666;
 
+
+  assertThrows(() => {
+    for (var x of g()) { break; }
+  }, TypeError);
+
   assertThrows(() => {
     for (let x of g()) { break; }
   }, TypeError);
 
   assertThrows(() => {
+    for (const x of g()) { break; }
+  }, TypeError);
+
+  assertThrows(() => {
     for (x of g()) { break; }
   }, TypeError);
 
-  assertThrows(() => {
+
+  // Throw from the body of a for loop 'wins' vs throw
+  // originating from a bad 'return' value.
+
+  assertThrowsEquals(() => {
+    for (var x of g()) { throw 666; }
+  }, 666);
+
+  assertThrowsEquals(() => {
     for (let x of g()) { throw 666; }
-  }, TypeError);
+  }, 666);
+
+  assertThrowsEquals(() => {
+    for (const x of g()) { throw 666; }
+  }, 666);
+
+  assertThrowsEquals(() => {
+    for (x of g()) { throw 666; }
+  }, 666);
+
 
   assertThrows(() => {
-    for (x of g()) { throw 666; }
+    for (var x of g()) { return 666; }
   }, TypeError);
 
   assertThrows(() => {
@@ -100,12 +233,42 @@
   }, TypeError);
 
   assertThrows(() => {
+    for (const x of g()) { return 666; }
+  }, TypeError);
+
+  assertThrows(() => {
     for (x of g()) { return 666; }
   }, TypeError);
 
+
+  assertEquals(42, eval('for (var x of g()) { x; }'));
+
   assertEquals(42, eval('for (let x of g()) { x; }'));
 
+  assertEquals(42, eval('for (const x of g()) { x; }'));
+
   assertEquals(42, eval('for (x of g()) { x; }'));
+
+
+  assertThrows(() => {
+    var [x] = g(); return x;
+  }, TypeError);
+
+  assertThrows(() => {
+    let [x] = g(); return x;
+  }, TypeError);
+
+  assertThrows(() => {
+    const [x] = g(); return x;
+  }, TypeError);
+
+  assertThrows(() => {
+    [x] = g(); return x;
+  }, TypeError);
+
+  assertThrows(() => {
+    (([x]) => x)(g());
+  }, TypeError);
 }
 
 
@@ -114,14 +277,30 @@
   let log = [];
   g.prototype.return = (...args) => { log.push(args); return {} };
 
+
+  log = [];
+  for (var x of g()) { break; }
+  assertEquals([[]], log);
+
   log = [];
   for (let x of g()) { break; }
   assertEquals([[]], log);
 
   log = [];
+  for (const x of g()) { break; }
+  assertEquals([[]], log);
+
+  log = [];
   for (x of g()) { break; }
   assertEquals([[]], log);
 
+
+  log = [];
+  assertThrowsEquals(() => {
+    for (var x of g()) { throw 42; }
+  }, 42);
+  assertEquals([[]], log);
+
   log = [];
   assertThrowsEquals(() => {
     for (let x of g()) { throw 42; }
@@ -130,10 +309,23 @@
 
   log = [];
   assertThrowsEquals(() => {
+    for (const x of g()) { throw 42; }
+  }, 42);
+  assertEquals([[]], log);
+
+  log = [];
+  assertThrowsEquals(() => {
     for (x of g()) { throw 42; }
   }, 42);
   assertEquals([[]], log);
 
+
+  log = [];
+  assertEquals(42, (() => {
+    for (var x of g()) { return 42; }
+  })());
+  assertEquals([[]], log);
+
   log = [];
   assertEquals(42, (() => {
     for (let x of g()) { return 42; }
@@ -142,17 +334,505 @@
 
   log = [];
   assertEquals(42, (() => {
+    for (const x of g()) { return 42; }
+  })());
+  assertEquals([[]], log);
+
+  log = [];
+  assertEquals(42, (() => {
     for (x of g()) { return 42; }
   })());
   assertEquals([[]], log);
 
+
+  log = [];
+  assertEquals(42, eval('for (var x of g()) { x; }'));
+  assertEquals([], log);
+
   log = [];
   assertEquals(42, eval('for (let x of g()) { x; }'));
   assertEquals([], log);
 
   log = [];
+  assertEquals(42, eval('for (const x of g()) { x; }'));
+  assertEquals([], log);
+
+  log = [];
   assertEquals(42, eval('for (x of g()) { x; }'));
   assertEquals([], log);
+
+
+  // Even if doing the assignment throws, still call return
+  log = [];
+  x = { set attr(_) { throw 1234; } };
+  assertThrowsEquals(() => {
+    for (x.attr of g()) { throw 456; }
+  }, 1234);
+  assertEquals([[]], log);
+
+
+  log = [];
+  assertEquals(42, (() => {
+    var [x] = g(); return x;
+  })());
+  assertEquals([[]], log);
+
+  log = [];
+  assertEquals(42, (() => {
+    let [x] = g(); return x;
+  })());
+  assertEquals([[]], log);
+
+  log = [];
+  assertEquals(42, (() => {
+    const [x] = g(); return x;
+  })());
+  assertEquals([[]], log);
+
+  log = [];
+  assertEquals(42, (() => {
+    [x] = g(); return x;
+  })());
+  assertEquals([[]], log);
+
+  log = []
+  assertEquals(42,
+    (([x]) => x)(g())
+  );
+  assertEquals([[]], log);
+
+
+  log = [];
+  assertEquals(42, (() => {
+    var [x,] = g(); return x;
+  })());
+  assertEquals([[]], log);
+
+  log = [];
+  assertEquals(42, (() => {
+    let [x,] = g(); return x;
+  })());
+  assertEquals([[]], log);
+
+  log = [];
+  assertEquals(42, (() => {
+    const [x,] = g(); return x;
+  })());
+  assertEquals([[]], log);
+
+  log = [];
+  assertEquals(42, (() => {
+    [x,] = g(); return x;
+  })());
+  assertEquals([[]], log);
+
+  log = []
+  assertEquals(42,
+    (([x,]) => x)(g())
+  );
+  assertEquals([[]], log);
+
+
+  log = [];
+  assertEquals(42, (() => {
+    var [x,,] = g(); return x;
+  })());
+  assertEquals([], log);
+
+  log = [];
+  assertEquals(42, (() => {
+    let [x,,] = g(); return x;
+  })());
+  assertEquals([], log);
+
+  log = [];
+  assertEquals(42, (() => {
+    const [x,,] = g(); return x;
+  })());
+  assertEquals([], log);
+
+  log = [];
+  assertEquals(42, (() => {
+    [x,,] = g(); return x;
+  })());
+  assertEquals([], log);
+
+  log = []
+  assertEquals(42,
+    (([x,,]) => x)(g())
+  );
+  assertEquals([], log);
+
+
+  log = [];
+  assertEquals([42, undefined], (() => {
+    var [x, y] = g(); return [x, y];
+  })());
+  assertEquals([], log);
+
+  log = [];
+  assertEquals([42, undefined], (() => {
+    let [x, y] = g(); return [x, y];
+  })());
+  assertEquals([], log);
+
+  log = [];
+  assertEquals([42, undefined], (() => {
+    const [x, y] = g(); return [x, y];
+  })());
+  assertEquals([], log);
+
+  log = [];
+  assertEquals([42, undefined], (() => {
+    [x, y] = g(); return [x, y];
+  })());
+  assertEquals([], log);
+
+  log = []
+  assertEquals([42, undefined],
+    (([x, y]) => [x, y])(g())
+  );
+  assertEquals([], log);
+
+
+  log = [];
+  assertEquals([42], (() => {
+    var [...x] = g(); return x;
+  })());
+  assertEquals([], log);
+
+  log = [];
+  assertEquals([42], (() => {
+    let [...x] = g(); return x;
+  })());
+  assertEquals([], log);
+
+  log = [];
+  assertEquals([42], (() => {
+    const [...x] = g(); return x;
+  })());
+  assertEquals([], log);
+
+  log = [];
+  assertEquals([42], (() => {
+    [...x] = g(); return x;
+  })());
+  assertEquals([], log);
+
+  log = []
+  assertEquals([42],
+    (([...x]) => x)(g())
+  );
+  assertEquals([], log);
+
+
+  log = [];
+  assertEquals([42, []], (() => {
+    var [x, ...y] = g(); return [x, y];
+  })());
+  assertEquals([], log);
+
+  log = [];
+  assertEquals([42, []], (() => {
+    let [x, ...y] = g(); return [x, y];
+  })());
+  assertEquals([], log);
+
+  log = [];
+  assertEquals([42, []], (() => {
+    const [x, ...y] = g(); return [x, y];
+  })());
+  assertEquals([], log);
+
+  log = [];
+  assertEquals([42, []], (() => {
+    [x, ...y] = g(); return [x, y];
+  })());
+  assertEquals([], log);
+
+  log = []
+  assertEquals([42, []],
+    (([x, ...y]) => [x, y])(g())
+  );
+  assertEquals([], log);
+
+
+  log = [];
+  assertEquals([], (() => {
+    var [] = g(); return [];
+  })());
+  assertEquals([[]], log);
+
+  log = [];
+  assertEquals([], (() => {
+    let [] = g(); return [];
+  })());
+  assertEquals([[]], log);
+
+  log = [];
+  assertEquals([], (() => {
+    const [] = g(); return [];
+  })());
+  assertEquals([[]], log);
+
+  log = [];
+  assertEquals([], (() => {
+    [] = g(); return [];
+  })());
+  assertEquals([[]], log);
+
+  log = []
+  assertEquals([],
+    (([]) => [])(g())
+  );
+  assertEquals([[]], log);
+
+
+  log = [];
+  assertEquals([], (() => {
+    var [...[]] = g(); return [];
+  })());
+  assertEquals([], log);
+
+  log = [];
+  assertEquals([], (() => {
+    let [...[]] = g(); return [];
+  })());
+  assertEquals([], log);
+
+  log = [];
+  assertEquals([], (() => {
+    const [...[]] = g(); return [];
+  })());
+  assertEquals([], log);
+
+  log = [];
+  assertEquals([], (() => {
+    [...[]] = g(); return [];
+  })());
+  assertEquals([], log);
+
+  log = []
+  assertEquals([],
+    (([...[]]) => [])(g())
+  );
+  assertEquals([], log);
+
+
+  log = [];
+  assertEquals([42], (() => {
+    var [...[x]] = g(); return [x];
+  })());
+  assertEquals([], log);
+
+  log = [];
+  assertEquals([42], (() => {
+    let [...[x]] = g(); return [x];
+  })());
+  assertEquals([], log);
+
+  log = [];
+  assertEquals([42], (() => {
+    const [...[x]] = g(); return [x];
+  })());
+  assertEquals([], log);
+
+  log = [];
+  assertEquals([42], (() => {
+    [...[x]] = g(); return [x];
+  })());
+  assertEquals([], log);
+
+  log = []
+  assertEquals([42],
+    (([...[x]]) => [x])(g())
+  );
+  assertEquals([], log);
+
+
+  log = [];
+  assertEquals([42, undefined], (() => {
+    var [...[x, y]] = g(); return [x, y];
+  })());
+  assertEquals([], log);
+
+  log = [];
+  assertEquals([42, undefined], (() => {
+    let [...[x, y]] = g(); return [x, y];
+  })());
+  assertEquals([], log);
+
+  log = [];
+  assertEquals([42, undefined], (() => {
+    const [...[x, y]] = g(); return [x, y];
+  })());
+  assertEquals([], log);
+
+  log = [];
+  assertEquals([42, undefined], (() => {
+    [...[x, y]] = g(); return [x, y];
+  })());
+  assertEquals([], log);
+
+  log = []
+  assertEquals([42, undefined],
+    (([...[x, y]]) => [x, y])(g())
+  );
+  assertEquals([], log);
+
+
+  log = []
+  assertThrowsEquals(() => {
+    let x = { set foo(_) { throw 666; } };
+    [x.foo] = g();
+  }, 666);
+  assertEquals([[]], log);
+
+
+  log = []
+  assertThrows(() => {
+    var [[]] = g();
+  }, TypeError);
+  assertEquals([[]], log);
+
+  log = []
+  assertThrows(() => {
+    let [[]] = g();
+  }, TypeError);
+  assertEquals([[]], log);
+
+  log = []
+  assertThrows(() => {
+    const [[]] = g();
+  }, TypeError);
+  assertEquals([[]], log);
+
+  log = []
+  assertThrows(() => {
+    [[]] = g();
+  }, TypeError);
+  assertEquals([[]], log);
+
+  log = []
+  assertThrows(() => {
+    (([[]]) => 0)(g());
+  }, TypeError);
+  assertEquals([[]], log);
+
+
+  log = []
+  assertThrows(() => {
+    var [...[[]]] = g();
+  }, TypeError);
+  assertEquals([], log);
+
+  log = []
+  assertThrows(() => {
+    let [...[[]]] = g();
+  }, TypeError);
+  assertEquals([], log);
+
+  log = []
+  assertThrows(() => {
+    const [...[[]]] = g();
+  }, TypeError);
+  assertEquals([], log);
+
+  log = []
+  assertThrows(() => {
+    [...[[]]] = g();
+  }, TypeError);
+  assertEquals([], log);
+
+  log = []
+  assertThrows(() => {
+    (([...[[]]]) => 0)(g());
+  }, TypeError);
+  assertEquals([], log);
+
+
+  {
+    let backup = Array.prototype[Symbol.iterator];
+    Array.prototype[Symbol.iterator] = () => g();
+
+
+    log = [];
+    assertDoesNotThrow(() => {
+      var [x, ...[y]] = [1, 2, 3]
+    });
+    assertEquals(log, [[]]);
+
+    log = [];
+    assertDoesNotThrow(() => {
+      let [x, ...[y]] = [1, 2, 3];
+    });
+    assertEquals(log, [[]]);
+
+    log = [];
+    assertDoesNotThrow(() => {
+      const [x, ...[y]] = [1, 2, 3];
+    });
+    assertEquals(log, [[]]);
+
+    log = [];
+    assertDoesNotThrow(() => {
+      (([x, ...[y]]) => {})([1, 2, 3]);
+    });
+    assertEquals(log, [[]]);
+
+
+    log = [];
+    assertThrows(() => {
+      var [x, ...[[]]] = [1, 2, 3];
+    }, TypeError);
+    assertEquals(log, [[]]);
+
+    log = [];
+    assertThrows(() => {
+      let [x, ...[[]]] = [1, 2, 3];
+    }, TypeError);
+    assertEquals(log, [[]]);
+
+    log = [];
+    assertThrows(() => {
+      const [x, ...[[]]] = [1, 2, 3];
+    }, TypeError);
+    assertEquals(log, [[]]);
+
+    log = [];
+    assertThrows(() => {
+      (([x, ...[[]]]) => {})([1, 2, 3]);
+    }, TypeError);
+    assertEquals(log, [[]]);
+
+
+    log = [];
+    assertDoesNotThrow(() => {
+      var [x, ...[...y]] = [1, 2, 3];
+    });
+    assertEquals(log, []);
+
+    log = [];
+    assertDoesNotThrow(() => {
+      let [x, ...[...y]] = [1, 2, 3];
+    });
+    assertEquals(log, []);
+
+    log = [];
+    assertDoesNotThrow(() => {
+      const [x, ...[...y]] = [1, 2, 3];
+    });
+    assertEquals(log, []);
+
+    log = [];
+    assertDoesNotThrow(() => {
+      (([x, ...[...y]]) => {})([1, 2, 3]);
+    });
+    assertEquals(log, []);
+
+
+    Array.prototype[Symbol.iterator] = backup;
+  }
 }
 
 
@@ -161,6 +841,13 @@
   let log = [];
   g.prototype.return = (...args) => { log.push(args); throw 23 };
 
+
+  log = [];
+  assertThrowsEquals(() => {
+    for (var x of g()) { break; }
+  }, 23);
+  assertEquals([[]], log);
+
   log = [];
   assertThrowsEquals(() => {
     for (let x of g()) { break; }
@@ -169,10 +856,23 @@
 
   log = [];
   assertThrowsEquals(() => {
+    for (const x of g()) { break; }
+  }, 23);
+  assertEquals([[]], log);
+
+  log = [];
+  assertThrowsEquals(() => {
     for (x of g()) { break; }
   }, 23);
   assertEquals([[]], log);
 
+
+  log = [];
+  assertThrowsEquals(() => {
+    for (var x of g()) { throw 42; }
+  }, 42);
+  assertEquals([[]], log);
+
   log = [];
   assertThrowsEquals(() => {
     for (let x of g()) { throw 42; }
@@ -181,10 +881,23 @@
 
   log = [];
   assertThrowsEquals(() => {
+    for (const x of g()) { throw 42; }
+  }, 42);
+  assertEquals([[]], log);
+
+  log = [];
+  assertThrowsEquals(() => {
     for (x of g()) { throw 42; }
   }, 42);
   assertEquals([[]], log);
 
+
+  log = [];
+  assertThrowsEquals(() => {
+    for (var x of g()) { return 42; }
+  }, 23);
+  assertEquals([[]], log);
+
   log = [];
   assertThrowsEquals(() => {
     for (let x of g()) { return 42; }
@@ -193,17 +906,63 @@
 
   log = [];
   assertThrowsEquals(() => {
+    for (const x of g()) { return 42; }
+  }, 23);
+  assertEquals([[]], log);
+
+  log = [];
+  assertThrowsEquals(() => {
     for (x of g()) { return 42; }
   }, 23);
   assertEquals([[]], log);
 
+
+  log = [];
+  assertEquals(42, eval('for (var x of g()) { x; }'));
+  assertEquals([], log);
+
   log = [];
   assertEquals(42, eval('for (let x of g()) { x; }'));
   assertEquals([], log);
 
   log = [];
+  assertEquals(42, eval('for (const x of g()) { x; }'));
+  assertEquals([], log);
+
+  log = [];
   assertEquals(42, eval('for (x of g()) { x; }'));
   assertEquals([], log);
+
+
+  log = [];
+  assertThrowsEquals(() => {
+    var [x] = g(); return x;
+  }, 23);
+  assertEquals([[]], log);
+
+  log = [];
+  assertThrowsEquals(() => {
+    let [x] = g(); return x;
+  }, 23);
+  assertEquals([[]], log);
+
+  log = [];
+  assertThrowsEquals(() => {
+    const [x] = g(); return x;
+  }, 23);
+  assertEquals([[]], log);
+
+  log = [];
+  assertThrowsEquals(() => {
+    [x] = g(); return x;
+  }, 23);
+  assertEquals([[]], log);
+
+  log = [];
+  assertThrowsEquals(() => {
+    (([x]) => x)(g())
+  }, 23);
+  assertEquals([[]], log);
 }
 
 
@@ -212,13 +971,130 @@
   g.prototype.next = () => { throw 666; };
   g.prototype.return = () => { assertUnreachable() };
 
+
+  assertThrowsEquals(() => {
+    for (var x of g()) {}
+  }, 666);
+
   assertThrowsEquals(() => {
     for (let x of g()) {}
   }, 666);
 
   assertThrowsEquals(() => {
+    for (const x of g()) {}
+  }, 666);
+
+  assertThrowsEquals(() => {
     for (x of g()) {}
   }, 666);
+
+  assertThrowsEquals(() => {
+    var [x] = g();
+  }, 666);
+
+  assertThrowsEquals(() => {
+    let [x] = g();
+  }, 666);
+
+  assertThrowsEquals(() => {
+    const [x] = g();
+  }, 666);
+
+  assertThrowsEquals(() => {
+    [x] = g();
+  }, 666);
+
+  assertThrowsEquals(() => {
+    (([x]) => x)(g());
+  }, 666);
+}
+
+
+// Value throws.
+{
+  g.prototype.next = () => ({get value() {throw 666}});
+  g.prototype.return = () => { assertUnreachable() };
+
+
+  assertThrowsEquals(() => {
+    for (var x of g()) {}
+  }, 666);
+
+  assertThrowsEquals(() => {
+    for (let x of g()) {}
+  }, 666);
+
+  assertThrowsEquals(() => {
+    for (const x of g()) {}
+  }, 666);
+
+  assertThrowsEquals(() => {
+    for (x of g()) {}
+  }, 666);
+
+  assertThrowsEquals(() => {
+    var [x] = g();
+  }, 666);
+
+  assertThrowsEquals(() => {
+    let [x] = g();
+  }, 666);
+
+  assertThrowsEquals(() => {
+    const [x] = g();
+  }, 666);
+
+  assertThrowsEquals(() => {
+    [x] = g();
+  }, 666);
+
+  assertThrowsEquals(() => {
+    (([x]) => x)(g());
+  }, 666);
+}
+
+
+// Done throws.
+{
+  g.prototype.next = () => ({get done() {throw 666}});
+  g.prototype.return = () => { assertUnreachable() };
+
+
+  assertThrowsEquals(() => {
+    for (var x of g()) {}
+  }, 666);
+
+  assertThrowsEquals(() => {
+    for (let x of g()) {}
+  }, 666);
+
+  assertThrowsEquals(() => {
+    for (const x of g()) {}
+  }, 666);
+
+  assertThrowsEquals(() => {
+    for (x of g()) {}
+  }, 666);
+
+  assertThrowsEquals(() => {
+    var [x] = g();
+  }, 666);
+
+  assertThrowsEquals(() => {
+    let [x] = g();
+  }, 666);
+
+  assertThrowsEquals(() => {
+    const [x] = g();
+  }, 666);
+
+  assertThrowsEquals(() => {
+    [x] = g();
+  }, 666);
+
+  assertThrowsEquals(() => {
+    (([x]) => x)(g());
+  }, 666);
 }