Merge V8 5.3.332.45.  DO NOT MERGE

Test: Manual

FPIIM-449

Change-Id: Id3254828b068abdea3cb10442e0172a8c9a98e03
(cherry picked from commit 13e2dadd00298019ed862f2b2fc5068bba730bcf)
diff --git a/test/mjsunit/harmony/array-species-constructor-accessor.js b/test/mjsunit/harmony/array-species-constructor-accessor.js
deleted file mode 100644
index 4c852f0..0000000
--- a/test/mjsunit/harmony/array-species-constructor-accessor.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-species --allow-natives-syntax
-
-// Overwriting the constructor of an instance updates the protector
-
-let x = [];
-
-assertEquals(Array, x.map(()=>{}).constructor);
-assertEquals(Array, x.filter(()=>{}).constructor);
-assertEquals(Array, x.slice().constructor);
-assertEquals(Array, x.splice().constructor);
-assertEquals(Array, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
-
-class MyArray extends Array { }
-
-Object.defineProperty(x, 'constructor', {get() { return MyArray; }});
-assertFalse(%SpeciesProtector());
-
-assertEquals(MyArray, x.map(()=>{}).constructor);
-assertEquals(MyArray, x.filter(()=>{}).constructor);
-assertEquals(MyArray, x.slice().constructor);
-assertEquals(MyArray, x.splice().constructor);
-assertEquals(MyArray, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
diff --git a/test/mjsunit/harmony/array-species-constructor-delete.js b/test/mjsunit/harmony/array-species-constructor-delete.js
deleted file mode 100644
index f341282..0000000
--- a/test/mjsunit/harmony/array-species-constructor-delete.js
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-species --allow-natives-syntax
-
-// Overwriting the constructor of an instance updates the protector
-
-let x = [];
-
-assertEquals(Array, x.map(()=>{}).constructor);
-assertEquals(Array, x.filter(()=>{}).constructor);
-assertEquals(Array, x.slice().constructor);
-assertEquals(Array, x.splice().constructor);
-assertEquals(Array, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
-
-class MyArray extends Array { }
-
-Object.prototype.constructor = MyArray;
-delete Array.prototype.constructor;
-assertFalse(%SpeciesProtector());
-
-assertEquals(MyArray, x.map(()=>{}).constructor);
-assertEquals(MyArray, x.filter(()=>{}).constructor);
-assertEquals(MyArray, x.slice().constructor);
-assertEquals(MyArray, x.splice().constructor);
-assertEquals(MyArray, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
diff --git a/test/mjsunit/harmony/array-species-constructor.js b/test/mjsunit/harmony/array-species-constructor.js
deleted file mode 100644
index d766e09..0000000
--- a/test/mjsunit/harmony/array-species-constructor.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-species --allow-natives-syntax
-
-// Overwriting the constructor of an instance updates the protector
-
-let x = [];
-
-assertEquals(Array, x.map(()=>{}).constructor);
-assertEquals(Array, x.filter(()=>{}).constructor);
-assertEquals(Array, x.slice().constructor);
-assertEquals(Array, x.splice().constructor);
-assertEquals(Array, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
-
-class MyArray extends Array { }
-
-x.constructor = MyArray;
-assertFalse(%SpeciesProtector());
-
-assertEquals(MyArray, x.map(()=>{}).constructor);
-assertEquals(MyArray, x.filter(()=>{}).constructor);
-assertEquals(MyArray, x.slice().constructor);
-assertEquals(MyArray, x.splice().constructor);
-assertEquals(MyArray, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
diff --git a/test/mjsunit/harmony/array-species-delete.js b/test/mjsunit/harmony/array-species-delete.js
deleted file mode 100644
index ba49414..0000000
--- a/test/mjsunit/harmony/array-species-delete.js
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-species --allow-natives-syntax
-
-// Overwriting the constructor of an instance updates the protector
-
-let x = [];
-
-assertEquals(Array, x.map(()=>{}).constructor);
-assertEquals(Array, x.filter(()=>{}).constructor);
-assertEquals(Array, x.slice().constructor);
-assertEquals(Array, x.splice().constructor);
-assertEquals(Array, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
-
-class MyArray extends Array { }
-
-Object.prototype[Symbol.species] = MyArray;
-delete Array[Symbol.species];
-assertFalse(%SpeciesProtector());
-
-assertEquals(MyArray, x.map(()=>{}).constructor);
-assertEquals(MyArray, x.filter(()=>{}).constructor);
-assertEquals(MyArray, x.slice().constructor);
-assertEquals(MyArray, x.splice().constructor);
-assertEquals(MyArray, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
diff --git a/test/mjsunit/harmony/array-species-modified.js b/test/mjsunit/harmony/array-species-modified.js
deleted file mode 100644
index 73c52b9..0000000
--- a/test/mjsunit/harmony/array-species-modified.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-species --allow-natives-syntax
-
-// Overwriting Array[Symbol.species] updates the protector
-
-let x = [];
-
-assertEquals(Array, x.map(()=>{}).constructor);
-assertEquals(Array, x.filter(()=>{}).constructor);
-assertEquals(Array, x.slice().constructor);
-assertEquals(Array, x.splice().constructor);
-assertEquals(Array, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
-
-class MyArray extends Array { }
-
-Object.defineProperty(Array, Symbol.species, {value: MyArray});
-assertFalse(%SpeciesProtector());
-
-assertEquals(MyArray, x.map(()=>{}).constructor);
-assertEquals(MyArray, x.filter(()=>{}).constructor);
-assertEquals(MyArray, x.slice().constructor);
-assertEquals(MyArray, x.splice().constructor);
-assertEquals(MyArray, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
diff --git a/test/mjsunit/harmony/array-species-parent-constructor.js b/test/mjsunit/harmony/array-species-parent-constructor.js
deleted file mode 100644
index 347732e..0000000
--- a/test/mjsunit/harmony/array-species-parent-constructor.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-species --allow-natives-syntax
-
-// Overwriting Array.prototype.constructor updates the protector
-
-let x = [];
-
-assertEquals(Array, x.map(()=>{}).constructor);
-assertEquals(Array, x.filter(()=>{}).constructor);
-assertEquals(Array, x.slice().constructor);
-assertEquals(Array, x.splice().constructor);
-assertEquals(Array, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
-
-class MyArray extends Array { }
-
-Array.prototype.constructor = MyArray;
-assertFalse(%SpeciesProtector());
-
-assertEquals(MyArray, x.map(()=>{}).constructor);
-assertEquals(MyArray, x.filter(()=>{}).constructor);
-assertEquals(MyArray, x.slice().constructor);
-assertEquals(MyArray, x.splice().constructor);
-assertEquals(MyArray, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
diff --git a/test/mjsunit/harmony/array-species-proto.js b/test/mjsunit/harmony/array-species-proto.js
deleted file mode 100644
index 70db751..0000000
--- a/test/mjsunit/harmony/array-species-proto.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-species --allow-natives-syntax
-
-// Overwriting an array instance's __proto__ updates the protector
-
-let x = [];
-
-assertEquals(Array, x.map(()=>{}).constructor);
-assertEquals(Array, x.filter(()=>{}).constructor);
-assertEquals(Array, x.slice().constructor);
-assertEquals(Array, x.splice().constructor);
-assertEquals(Array, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
-
-class MyArray extends Array { }
-
-x.__proto__ = MyArray.prototype;
-assertTrue(%SpeciesProtector());
-
-assertEquals(MyArray, x.map(()=>{}).constructor);
-assertEquals(MyArray, x.filter(()=>{}).constructor);
-assertEquals(MyArray, x.slice().constructor);
-assertEquals(MyArray, x.splice().constructor);
-assertEquals(MyArray, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
diff --git a/test/mjsunit/harmony/array-species.js b/test/mjsunit/harmony/array-species.js
deleted file mode 100644
index 19ed1d8..0000000
--- a/test/mjsunit/harmony/array-species.js
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-species
-
-// Test the ES2015 @@species feature
-
-'use strict';
-
-// Subclasses of Array construct themselves under map, etc
-
-class MyArray extends Array { }
-
-assertEquals(MyArray, new MyArray().map(()=>{}).constructor);
-assertEquals(MyArray, new MyArray().filter(()=>{}).constructor);
-assertEquals(MyArray, new MyArray().slice().constructor);
-assertEquals(MyArray, new MyArray().splice().constructor);
-assertEquals(MyArray, new MyArray().concat([1]).constructor);
-assertEquals(1, new MyArray().concat([1])[0]);
-
-// Subclasses can override @@species to return the another class
-
-class MyOtherArray extends Array {
-  static get [Symbol.species]() { return MyArray; }
-}
-
-assertEquals(MyArray, new MyOtherArray().map(()=>{}).constructor);
-assertEquals(MyArray, new MyOtherArray().filter(()=>{}).constructor);
-assertEquals(MyArray, new MyOtherArray().slice().constructor);
-assertEquals(MyArray, new MyOtherArray().splice().constructor);
-assertEquals(MyArray, new MyOtherArray().concat().constructor);
-
-// Array  methods on non-arrays return arrays
-
-class MyNonArray extends Array {
-  static get [Symbol.species]() { return MyObject; }
-}
-
-class MyObject { }
-
-assertEquals(MyObject,
-             Array.prototype.map.call(new MyNonArray(), ()=>{}).constructor);
-assertEquals(MyObject,
-             Array.prototype.filter.call(new MyNonArray(), ()=>{}).constructor);
-assertEquals(MyObject,
-             Array.prototype.slice.call(new MyNonArray()).constructor);
-assertEquals(MyObject,
-             Array.prototype.splice.call(new MyNonArray()).constructor);
-assertEquals(MyObject,
-             Array.prototype.concat.call(new MyNonArray()).constructor);
-
-assertEquals(undefined,
-             Array.prototype.map.call(new MyNonArray(), ()=>{}).length);
-assertEquals(undefined,
-             Array.prototype.filter.call(new MyNonArray(), ()=>{}).length);
-assertEquals(undefined,
-             Array.prototype.concat.call(new MyNonArray(), ()=>{}).length);
-// slice and splice actually do explicitly define the length for some reason
-assertEquals(0, Array.prototype.slice.call(new MyNonArray()).length);
-assertEquals(0, Array.prototype.splice.call(new MyNonArray()).length);
-
-// Cross-realm Arrays build same-realm arrays
-
-var realm = Realm.create();
-assertEquals(Array,
-             Array.prototype.map.call(
-                 Realm.eval(realm, "[]"), ()=>{}).constructor);
-assertFalse(Array === Realm.eval(realm, "[]").map(()=>{}).constructor);
-assertFalse(Array === Realm.eval(realm, "[].map(()=>{}).constructor"));
-assertEquals(Array,
-             Array.prototype.concat.call(
-                 Realm.eval(realm, "[]")).constructor);
-
-// Defaults when constructor or @@species is missing or non-constructor
-
-class MyDefaultArray extends Array {
-  static get [Symbol.species]() { return undefined; }
-}
-assertEquals(Array, new MyDefaultArray().map(()=>{}).constructor);
-
-class MyOtherDefaultArray extends Array { }
-assertEquals(MyOtherDefaultArray,
-             new MyOtherDefaultArray().map(()=>{}).constructor);
-MyOtherDefaultArray.prototype.constructor = undefined;
-assertEquals(Array, new MyOtherDefaultArray().map(()=>{}).constructor);
-assertEquals(Array, new MyOtherDefaultArray().concat().constructor);
-
-// Exceptions propagated when getting constructor @@species throws
-
-class SpeciesError extends Error { }
-class ConstructorError extends Error { }
-class MyThrowingArray extends Array {
-  static get [Symbol.species]() { throw new SpeciesError; }
-}
-assertThrows(() => new MyThrowingArray().map(()=>{}), SpeciesError);
-Object.defineProperty(MyThrowingArray.prototype, 'constructor', {
-    get() { throw new ConstructorError; }
-});
-assertThrows(() => new MyThrowingArray().map(()=>{}), ConstructorError);
-
-// Previously unexpected errors from setting properties in arrays throw
-
-class FrozenArray extends Array {
-  constructor(...args) {
-    super(...args);
-    Object.freeze(this);
-  }
-}
-assertThrows(() => new FrozenArray([1]).map(()=>0), TypeError);
-assertThrows(() => new FrozenArray([1]).filter(()=>true), TypeError);
-assertThrows(() => new FrozenArray([1]).slice(0, 1), TypeError);
-assertThrows(() => new FrozenArray([1]).splice(0, 1), TypeError);
-assertThrows(() => new FrozenArray([]).concat([1]), TypeError);
-
-// Verify call counts and constructor parameters
-
-var count;
-var params;
-class MyObservedArray extends Array {
-  constructor(...args) {
-    super(...args);
-    params = args;
-  }
-  static get [Symbol.species]() {
-    count++
-    return this;
-  }
-}
-
-count = 0;
-params = undefined;
-assertEquals(MyObservedArray,
-             new MyObservedArray().map(()=>{}).constructor);
-assertEquals(1, count);
-assertArrayEquals([0], params);
-
-count = 0;
-params = undefined;
-assertEquals(MyObservedArray,
-             new MyObservedArray().filter(()=>{}).constructor);
-assertEquals(1, count);
-assertArrayEquals([0], params);
-
-count = 0;
-params = undefined;
-assertEquals(MyObservedArray,
-             new MyObservedArray().concat().constructor);
-assertEquals(1, count);
-assertArrayEquals([0], params);
-
-count = 0;
-params = undefined;
-assertEquals(MyObservedArray,
-             new MyObservedArray().slice().constructor);
-assertEquals(1, count);
-assertArrayEquals([0], params);
-
-count = 0;
-params = undefined;
-assertEquals(MyObservedArray,
-             new MyObservedArray().splice().constructor);
-assertEquals(1, count);
-assertArrayEquals([0], params);
-
-// @@species constructor can be a Proxy, and the realm access doesn't
-// crash
-
-class MyProxyArray extends Array { }
-let ProxyArray = new Proxy(MyProxyArray, {});
-MyProxyArray.constructor = ProxyArray;
-
-assertEquals(MyProxyArray, new ProxyArray().map(()=>{}).constructor);
diff --git a/test/mjsunit/harmony/arraybuffer-species.js b/test/mjsunit/harmony/arraybuffer-species.js
deleted file mode 100644
index 0445a4b..0000000
--- a/test/mjsunit/harmony/arraybuffer-species.js
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-species
-
-// ArrayBuffer.prototype.slice makes subclass and checks length
-
-class MyArrayBuffer extends ArrayBuffer { }
-assertEquals(MyArrayBuffer, new MyArrayBuffer(0).slice().constructor);
-
-class MyShortArrayBuffer extends ArrayBuffer {
-  constructor(length) { super(length - 1); }
-}
-assertThrows(() => new MyShortArrayBuffer(5).slice(0, 4), TypeError);
-
-class SingletonArrayBuffer extends ArrayBuffer {
-  constructor(...args) {
-    if (SingletonArrayBuffer.cached) return SingletonArrayBuffer.cached;
-    super(...args);
-    SingletonArrayBuffer.cached = this;
-  }
-}
-assertThrows(() => new SingletonArrayBuffer(5).slice(0, 4), TypeError);
-
-class NonArrayBuffer extends ArrayBuffer {
-  constructor() {
-    return {};
-  }
-}
-assertThrows(() => new NonArrayBuffer(5).slice(0, 4), TypeError);
-
-// Species fallback is ArrayBuffer
-class UndefinedArrayBuffer extends ArrayBuffer { }
-UndefinedArrayBuffer.prototype.constructor = undefined;
-assertEquals(ArrayBuffer, new UndefinedArrayBuffer(0).slice().constructor);
diff --git a/test/mjsunit/harmony/async-await-basic.js b/test/mjsunit/harmony/async-await-basic.js
index d0888ea..ba0350f 100644
--- a/test/mjsunit/harmony/async-await-basic.js
+++ b/test/mjsunit/harmony/async-await-basic.js
@@ -343,5 +343,27 @@
 assertEquals("async x => x", (async x => x).toString());
 assertEquals("async x => { return x }", (async x => { return x }).toString());
 class AsyncMethod { async foo() { } }
-assertEquals("async foo() { }", Function.prototype.toString.call(AsyncMethod.prototype.foo));
-assertEquals("async foo() { }", Function.prototype.toString.call({async foo() { }}.foo));
+assertEquals("async foo() { }",
+             Function.prototype.toString.call(AsyncMethod.prototype.foo));
+assertEquals("async foo() { }",
+             Function.prototype.toString.call({async foo() { }}.foo));
+
+// Async functions are not constructible
+assertThrows(() => class extends (async function() {}) {}, TypeError);
+
+// Regress v8:5148
+assertEqualsAsync("1", () => (async({ a = NaN }) => a)({ a: "1" }));
+assertEqualsAsync(
+    "10", () => (async(foo, { a = NaN }) => foo + a)("1", { a: "0" }));
+assertEqualsAsync("2", () => (async({ a = "2" }) => a)({ a: undefined }));
+assertEqualsAsync(
+    "20", () => (async(foo, { a = "0" }) => foo + a)("2", { a: undefined }));
+assertThrows(() => eval("async({ foo = 1 })"), SyntaxError);
+assertThrows(() => eval("async(a, { foo = 1 })"), SyntaxError);
+
+// https://bugs.chromium.org/p/chromium/issues/detail?id=638019
+async function gaga() {
+  let i = 1;
+  while (i-- > 0) { await 42 }
+}
+assertDoesNotThrow(gaga);
diff --git a/test/mjsunit/harmony/async-debug-basic.js b/test/mjsunit/harmony/async-debug-basic.js
new file mode 100644
index 0000000..a490972
--- /dev/null
+++ b/test/mjsunit/harmony/async-debug-basic.js
@@ -0,0 +1,40 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags:  --harmony-async-await --allow-natives-syntax --expose-debug-as debug
+
+// Get the Debug object exposed from the debug context global object.
+Debug = debug.Debug
+
+listenerComplete = false;
+breakPointCount = 0;
+
+async function f() {
+  await (async function() { var a = "a"; await 1; debugger; })();
+
+  var b = "b";
+
+  assertTrue(listenerDone);
+  assertFalse(exception);
+  assertEquals(1, breakpointCount);
+}
+
+function listener(event, exec_state, event_data, data) {
+  try {
+    if (event != Debug.DebugEvent.Break) return;
+
+    breakpointCount++;
+    listenerDone = true;
+    assertEquals("a", exec_state.frame(0).evaluate("a"));
+    assertEquals("b", exec_state.frame(1).evaluate("b"));
+    assertEquals("c", exec_state.frame(2).evaluate("c"));
+  } catch (e) {
+    exception = e;
+  };
+};
+
+Debug.setListener(listener);
+
+var c = "c";
+f();
diff --git a/test/mjsunit/harmony/async-debug-step-abort-at-break.js b/test/mjsunit/harmony/async-debug-step-abort-at-break.js
new file mode 100644
index 0000000..be1f805
--- /dev/null
+++ b/test/mjsunit/harmony/async-debug-step-abort-at-break.js
@@ -0,0 +1,55 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax --harmony-async-await
+
+var Debug = debug.Debug;
+var step_count = 0;
+
+function listener(event, execState, eventData, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    var line = execState.frame(0).sourceLineText();
+    print(line);
+    var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line);
+    assertEquals(step_count++, parseInt(expected_count));
+    if (step != "Continue") execState.prepareStep(Debug.StepAction[step]);
+  } catch (e) {
+    print(e, e.stack);
+    quit(1);
+  }
+}
+
+Debug.setListener(listener);
+
+var late_resolve;
+
+function g() {
+  return new Promise( // B3 StepOut
+    function(res, rej) {
+      late_resolve = res;
+    }
+  );
+}
+
+async function f() {
+  var a = 1;
+  debugger;          // B0 StepNext
+  a +=               // B1 StepNext
+       await         // B4 StepNext
+             g();    // B2 StepIn
+  return a;
+}
+
+f();
+
+// Starting a new step action at an intermediate break point
+// means that we will abort the current async step.
+debugger;            // B5 StepNext
+
+late_resolve(3);     // B6 Continue
+
+%RunMicrotasks();
+
+assertEquals(7, step_count);
diff --git a/test/mjsunit/harmony/async-debug-step-continue-at-break.js b/test/mjsunit/harmony/async-debug-step-continue-at-break.js
new file mode 100644
index 0000000..5099b2f
--- /dev/null
+++ b/test/mjsunit/harmony/async-debug-step-continue-at-break.js
@@ -0,0 +1,55 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax --harmony-async-await
+
+var Debug = debug.Debug;
+var step_count = 0;
+
+function listener(event, execState, eventData, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    var line = execState.frame(0).sourceLineText();
+    print(line);
+    var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line);
+    assertEquals(step_count++, parseInt(expected_count));
+    if (step != "Continue") execState.prepareStep(Debug.StepAction[step]);
+  } catch (e) {
+    print(e, e.stack);
+    quit(1);
+  }
+}
+
+Debug.setListener(listener);
+
+var late_resolve;
+
+function g() {
+  return new Promise( // B3 StepOut
+    function(res, rej) {
+      late_resolve = res;
+    }
+  );
+}
+
+async function f() {
+  var a = 1;
+  debugger;          // B0 StepNext
+  a +=               // B1 StepNext
+       await         // B4 StepNext
+             g();    // B2 StepIn
+  return a;          // B6 StepNext
+}                    // B7 Continue
+
+f();
+
+// Continuing at an intermediate break point means that we will
+// carry on with the current async step.
+debugger;            // B5 Continue
+
+late_resolve(3);
+
+%RunMicrotasks();
+
+assertEquals(8, step_count);
diff --git a/test/mjsunit/harmony/async-debug-step-in-and-out.js b/test/mjsunit/harmony/async-debug-step-in-and-out.js
new file mode 100644
index 0000000..30fe2d6
--- /dev/null
+++ b/test/mjsunit/harmony/async-debug-step-in-and-out.js
@@ -0,0 +1,51 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax --harmony-async-await
+
+var Debug = debug.Debug;
+var step_count = 0;
+
+function listener(event, execState, eventData, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    var line = execState.frame(0).sourceLineText();
+    print(line);
+    var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line);
+    assertEquals(step_count++, parseInt(expected_count));
+    if (step != "Continue") execState.prepareStep(Debug.StepAction[step]);
+  } catch (e) {
+    print(e, e.stack);
+    quit(1);
+  }
+}
+
+Debug.setListener(listener);
+
+var late_resolve;
+
+function g() {
+  return new Promise(  // B3 StepOut
+    function(res, rej) {
+      late_resolve = res;
+    }
+  );
+}
+
+async function f() {
+  var a = 1;
+  debugger;            // B0 StepNext
+  a +=                 // B1 StepNext
+       await           // B4 StepNext
+             g();      // B2 StepIn
+  return a;            // B5 StepNext
+}                      // B6 Continue
+
+f();
+
+late_resolve(3);
+
+%RunMicrotasks();
+
+assertEquals(7, step_count);
diff --git a/test/mjsunit/harmony/async-debug-step-in-out-out.js b/test/mjsunit/harmony/async-debug-step-in-out-out.js
new file mode 100644
index 0000000..c2f34bb
--- /dev/null
+++ b/test/mjsunit/harmony/async-debug-step-in-out-out.js
@@ -0,0 +1,51 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax --harmony-async-await
+
+var Debug = debug.Debug;
+var step_count = 0;
+
+function listener(event, execState, eventData, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    var line = execState.frame(0).sourceLineText();
+    print(line);
+    var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line);
+    assertEquals(step_count++, parseInt(expected_count));
+    if (step != "Continue") execState.prepareStep(Debug.StepAction[step]);
+  } catch (e) {
+    print(e, e.stack);
+    quit(1);
+  }
+}
+
+Debug.setListener(listener);
+
+var late_resolve;
+
+function g() {
+  return new Promise( // B3 StepOut
+    function(res, rej) {
+      late_resolve = res;
+    }
+  );
+}
+
+async function f() {
+  var a = 1;
+  debugger;        // B0 StepNext
+  a +=             // B1 StepNext
+       await       // B4 StepOut
+             g();  // B2 StepIn
+  return a;
+}
+
+f();
+
+late_resolve(3);   // B5 Continue
+
+%RunMicrotasks();
+
+assertEquals(6, step_count);
diff --git a/test/mjsunit/harmony/async-debug-step-in.js b/test/mjsunit/harmony/async-debug-step-in.js
new file mode 100644
index 0000000..0a7de1a
--- /dev/null
+++ b/test/mjsunit/harmony/async-debug-step-in.js
@@ -0,0 +1,51 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax --harmony-async-await
+
+var Debug = debug.Debug;
+var step_count = 0;
+
+function listener(event, execState, eventData, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    var line = execState.frame(0).sourceLineText();
+    print(line);
+    var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line);
+    assertEquals(step_count++, parseInt(expected_count));
+    if (step != "Continue") execState.prepareStep(Debug.StepAction[step]);
+  } catch (e) {
+    print(e, e.stack);
+    quit(1);
+  }
+}
+
+Debug.setListener(listener);
+
+var late_resolve;
+
+function g() {
+  return new Promise(  // B3 StepIn
+    function(res, rej) {
+      late_resolve = res;  // B4 StepIn
+    }                      // B5 StepIn
+  );
+}                      // B6 StepIn
+
+async function f() {
+  var a = 1;
+  debugger;            // B0 StepNext
+  a +=                 // B1 StepIn
+       await           // B7 StepIn
+             g();      // B2 StepIn
+  return a;            // B8 StepIn
+}                      // B9 Continue
+
+f().then(value => assertEquals(4, value));
+
+late_resolve(3);
+
+%RunMicrotasks();
+
+assertEquals(10, step_count);
diff --git a/test/mjsunit/harmony/async-debug-step-nested.js b/test/mjsunit/harmony/async-debug-step-nested.js
new file mode 100644
index 0000000..adf7a51
--- /dev/null
+++ b/test/mjsunit/harmony/async-debug-step-nested.js
@@ -0,0 +1,58 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax --harmony-async-await
+
+var Debug = debug.Debug;
+var step_count = 0;
+
+function listener(event, execState, eventData, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    var line = execState.frame(0).sourceLineText();
+    print(line);
+    var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line);
+    assertEquals(step_count++, parseInt(expected_count));
+    if (step != "Continue") execState.prepareStep(Debug.StepAction[step]);
+  } catch (e) {
+    print(e, e.stack);
+    quit(1);
+  }
+}
+
+Debug.setListener(listener);
+
+var late_resolve;
+
+function g() {
+  return new Promise( // B4 StepOut
+    function(res, rej) {
+      late_resolve = res;
+    }
+  );
+}
+
+async function f1() {
+  var a = 1;
+  debugger;          // B0 StepNext
+  a +=               // B1 StepNext
+       await         // B6 StepNext
+             f2();   // B2 StepIn
+  return a;          // B7 StepNext
+}                    // B8 Continue
+
+async function f2() {
+  var b =
+          await      // B5 StepOut
+                g(); // B3 StepIn
+  return b;
+}
+
+f1();
+
+late_resolve(3);
+
+%RunMicrotasks();
+
+assertEquals(9, step_count);
diff --git a/test/mjsunit/harmony/async-debug-step-next-constant.js b/test/mjsunit/harmony/async-debug-step-next-constant.js
new file mode 100644
index 0000000..cea86d7
--- /dev/null
+++ b/test/mjsunit/harmony/async-debug-step-next-constant.js
@@ -0,0 +1,39 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax --harmony-async-await
+
+var Debug = debug.Debug;
+var step_count = 0;
+
+function listener(event, execState, eventData, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    var line = execState.frame(0).sourceLineText();
+    print(line);
+    var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line);
+    assertEquals(step_count++, parseInt(expected_count));
+    if (step != "Continue") execState.prepareStep(Debug.StepAction[step]);
+  } catch (e) {
+    print(e, e.stack);
+    quit(1);
+  }
+}
+
+Debug.setListener(listener);
+
+async function f() {
+  var a = 1;
+  debugger;          // B0 StepNext
+  a +=               // B1 StepNext
+       await         // B3 StepNext
+             5;      // B2 StepNext
+  return a;          // B4 StepNext
+}                    // B5 Continue
+
+f();
+
+%RunMicrotasks();
+
+assertEquals(6, step_count);
diff --git a/test/mjsunit/harmony/async-debug-step-next.js b/test/mjsunit/harmony/async-debug-step-next.js
new file mode 100644
index 0000000..952d88d
--- /dev/null
+++ b/test/mjsunit/harmony/async-debug-step-next.js
@@ -0,0 +1,51 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax --harmony-async-await
+
+var Debug = debug.Debug;
+var step_count = 0;
+
+function listener(event, execState, eventData, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    var line = execState.frame(0).sourceLineText();
+    print(line);
+    var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line);
+    assertEquals(step_count++, parseInt(expected_count));
+    if (step != "Continue") execState.prepareStep(Debug.StepAction[step]);
+  } catch (e) {
+    print(e, e.stack);
+    quit(1);
+  }
+}
+
+Debug.setListener(listener);
+
+var late_resolve;
+
+function g() {
+  return new Promise(
+    function(res, rej) {
+      late_resolve = res;
+    }
+  );
+}
+
+async function f() {
+  var a = 1;
+  debugger;        // B0 StepNext
+  a +=             // B1 StepNext
+       await       // B3 StepNext
+             g();  // B2 StepNext
+  return a;        // B4 StepNext
+}                  // B5 Continue
+
+f();
+
+late_resolve(3);
+
+%RunMicrotasks();
+
+assertEquals(6, step_count);
diff --git a/test/mjsunit/harmony/async-debug-step-out.js b/test/mjsunit/harmony/async-debug-step-out.js
new file mode 100644
index 0000000..41779ac
--- /dev/null
+++ b/test/mjsunit/harmony/async-debug-step-out.js
@@ -0,0 +1,49 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax --harmony-async-await
+
+var Debug = debug.Debug;
+var step_count = 0;
+
+function listener(event, execState, eventData, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    var line = execState.frame(0).sourceLineText();
+    print(line);
+    var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line);
+    assertEquals(step_count++, parseInt(expected_count));
+    if (step != "Continue") execState.prepareStep(Debug.StepAction[step]);
+  } catch (e) {
+    print(e, e.stack);
+    quit(1);
+  }
+}
+
+Debug.setListener(listener);
+
+var late_resolve;
+
+function g() {
+  return new Promise(
+    function(res, rej) {
+      late_resolve = res;
+    }
+  );
+}
+
+async function f() {
+  var a = 1;
+  debugger;        // B0 StepNext
+  a += await g();  // B1 StepOut
+  return a;
+}
+
+f();
+
+late_resolve(3);   // B2 Continue
+
+%RunMicrotasks();
+
+assertEquals(3, step_count);
diff --git a/test/mjsunit/harmony/async-function-debug-evaluate.js b/test/mjsunit/harmony/async-function-debug-evaluate.js
new file mode 100644
index 0000000..edf7bca
--- /dev/null
+++ b/test/mjsunit/harmony/async-function-debug-evaluate.js
@@ -0,0 +1,139 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-async-await --expose-debug-as debug
+
+var Debug = debug.Debug;
+var breakPointCount = 0;
+
+function listener(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  ++breakPointCount;
+  try {
+    if (breakPointCount === 1) {
+      assertEquals(
+          "inner", exec_state.frame(0).evaluate("inner").value());
+      assertThrows(() => exec_state.frame(0).evaluate("letInner").value(),
+                   ReferenceError);
+      assertThrows(() => exec_state.frame(0).evaluate("constInner").value(),
+                   ReferenceError);
+
+      assertEquals("outer", exec_state.frame(0).evaluate("outer").value());
+      assertEquals(
+          "const outer", exec_state.frame(0).evaluate("constOuter").value());
+      assertEquals(
+          "let outer", exec_state.frame(0).evaluate("letOuter").value());
+
+      assertEquals("outer", exec_state.frame(1).evaluate("outer").value());
+      assertEquals(
+          "const outer", exec_state.frame(1).evaluate("constOuter").value());
+      assertEquals(
+          "let outer", exec_state.frame(1).evaluate("letOuter").value());
+
+      assertThrows(() => exec_state.frame(0).evaluate("withVar").value(),
+                   ReferenceError);
+
+    } else if (breakPointCount === 2) {
+      assertEquals(
+          "inner", exec_state.frame(0).evaluate("inner").value());
+      assertThrows(() => exec_state.frame(0).evaluate("letInner").value(),
+                   ReferenceError);
+      assertThrows(() => exec_state.frame(0).evaluate("constInner").value(),
+                   ReferenceError);
+
+      assertEquals(57, exec_state.frame(0).evaluate("x").value());
+      assertEquals(100, exec_state.frame(0).evaluate("y").value());
+
+      // From breakPointCount === 1 and later, it's not possible to access
+      // earlier framestates.
+      assertEquals("outer", exec_state.frame(0).evaluate("outer").value());
+      assertEquals(
+          "const outer", exec_state.frame(0).evaluate("constOuter").value());
+      assertEquals(
+          "let outer", exec_state.frame(0).evaluate("letOuter").value());
+
+      exec_state.frame(0).evaluate("x = `x later(${x})`");
+      exec_state.frame(0).evaluate("y = `y later(${y})`");
+      exec_state.frame(0).evaluate("z = `ZEE`");
+
+    } else if (breakPointCount === 3) {
+      assertEquals(
+          "inner", exec_state.frame(0).evaluate("inner").value());
+      assertEquals(
+          "let inner", exec_state.frame(0).evaluate("letInner").value());
+      assertEquals(
+          "const inner", exec_state.frame(0).evaluate("constInner").value());
+
+    } else if (breakPointCount === 4) {
+      assertEquals(
+          "oop", exec_state.frame(0).evaluate("error.message").value());
+      assertEquals(
+          "Error",
+          exec_state.frame(0).evaluate("error.constructor.name").value());
+      assertEquals("floof", exec_state.frame(0).evaluate("bun").value());
+      assertThrows(() => exec_state.frame(0).evaluate("cow").value(),
+                   ReferenceError);
+
+      assertEquals("outer", exec_state.frame(0).evaluate("outer").value());
+      assertEquals(
+          "const outer", exec_state.frame(0).evaluate("constOuter").value());
+      assertEquals(
+          "let outer", exec_state.frame(0).evaluate("letOuter").value());
+    }
+  } catch (e) {
+    print(e.stack);
+    quit(1);
+  }
+}
+
+Debug.setListener(listener);
+
+var outer = "outer";
+const constOuter = "const outer";
+let letOuter = "let outer"
+
+async function thrower() {
+  return Promise.reject(new Error("oop"));
+}
+
+async function testLater() {
+  return { x: 57, y: 100 };
+}
+
+async function test() {
+  var inner = "inner";
+  debugger;
+
+  let withVar = await testLater();
+  with (withVar) {
+    debugger;
+  }
+
+  assertEquals("x later(57)", withVar.x);
+  assertEquals("y later(100)", withVar.y);
+  assertEquals(undefined, withVar.z);
+  assertEquals("ZEE", z);
+
+  let letInner = "let inner";
+  const constInner = "const inner";
+  debugger;
+
+  try {
+    await thrower();
+  } catch (error) {
+    const bun = "floof";
+    debugger;
+    let cow = "moo";
+  }
+}
+
+test().
+then(x => {
+  Debug.setListener(null);
+}).
+catch(error => {
+  print(error.stack);
+  quit(1);
+  Debug.setListener(null);
+});
diff --git a/test/mjsunit/harmony/async-function-debug-scopes.js b/test/mjsunit/harmony/async-function-debug-scopes.js
new file mode 100644
index 0000000..3d72549
--- /dev/null
+++ b/test/mjsunit/harmony/async-function-debug-scopes.js
@@ -0,0 +1,616 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-async-await --expose-debug-as debug
+
+var Debug = debug.Debug;
+
+var AsyncFunction = (async function() {}).constructor;
+
+async function thrower() { throw 'Exception'; }
+
+async function test(name, func, args, handler, continuation) {
+  var handler_called = false;
+  var exception = null;
+
+  function listener(event, exec_state, event_data, data) {
+    try {
+      if (event == Debug.DebugEvent.Break) {
+        handler_called = true;
+        handler(exec_state);
+      }
+    } catch (e) {
+      exception = e;
+    }
+  }
+
+  Debug.setListener(listener);
+
+  var result;
+  if (typeof func === "object")
+    result = await func.method.apply(func, args);
+  else
+    result = await func.apply(null, args);
+
+  if (typeof continuation === "function") {
+    await continuation(result);
+  }
+
+  assertTrue(handler_called, `Expected ${name} handler to be called`);
+  if (exception) {
+    exception.message = `${name} / ${exception.message}`;
+    print(exception.stack);
+    quit(1);
+  }
+
+  Debug.setListener(null);
+}
+
+async function runTests() {
+
+// Simple
+await test(
+    "(AsyncFunctionExpression) Local 1",
+    async function() { debugger; }, [],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({}, 0, exec_state);
+    });
+
+await test(
+    "(AsyncFunctionExpression) Local 1 --- resume normal",
+    async function() { let z = await 2; debugger; }, [],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({z: 2}, 0, exec_state);
+    });
+
+await test(
+    "(AsyncFunctionExpression) Local 1 --- resume throw",
+    async function() { let q = await 1;
+                       try { let z = await thrower(); }
+                       catch (e) { debugger; } }, [],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Catch,
+                       debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({e: 'Exception'}, 0, exec_state);
+      CheckScopeContent({q: 1}, 1, exec_state);
+
+    });
+
+// Simple With Parameter
+await test(
+    "(AsyncFunctionExpression) Local 2",
+    async function(a) { debugger; }, [1],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({ a: 1 }, 0, exec_state);
+    });
+
+await test(
+    "(AsyncFunctionExpression) Local 2 --- resume normal",
+    async function(a) { let z = await 2; debugger; }, [1],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({ a: 1, z: 2 }, 0, exec_state);
+    });
+
+await test(
+    "(AsyncFunctionExpression) Local 2 --- resume throw",
+    async function(a) { let z = await 2;
+                        try { await thrower(); } catch (e) { debugger; } }, [1],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Catch,
+                       debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({ e: 'Exception' }, 0, exec_state);
+      CheckScopeContent({ a: 1, z: 2 }, 1, exec_state);
+    });
+
+// Simple With Parameter and Variable
+await test(
+    "(AsyncFunctionExpression) Local 3",
+    async function(a) { var b = 2; debugger; }, [1],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({ a: 1, b: 2 }, 0, exec_state);
+    });
+
+await test(
+    "(AsyncFunctionExpression) Local 3 --- resume normal",
+    async function(a) { let y = await 3; var b = 2; let z = await 4;
+                        debugger; }, [1],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({ a: 1, b: 2, y: 3, z: 4 }, 0, exec_state);
+    });
+
+await test(
+    "(AsyncFunctionExpression) Local 3 --- resume throw",
+    async function(a) { let y = await 3;
+                        try { var b = 2; let z = await thrower(); }
+                        catch (e) { debugger; } }, [1],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Catch,
+                       debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({ e: 'Exception' }, 0, exec_state);
+      CheckScopeContent({ a: 1, b: 2, y: 3 }, 1, exec_state);
+    });
+
+// Local scope with parameters and local variables.
+await test(
+    "(AsyncFunctionExpression) Local 4",
+    async function(a, b) { var x = 3; var y = 4; debugger; }, [1, 2],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({a:1,b:2,x:3,y:4}, 0, exec_state);
+    });
+
+await test(
+    "(AsyncFunctionExpression) Local 4 --- resume normal",
+    async function(a, b) { let q = await 5; var x = 3; var y = 4;
+                           let r = await 6; debugger; }, [1, 2],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({a:1,b:2,x:3,y:4, q: 5, r: 6}, 0, exec_state);
+    });
+
+await test(
+    "(AsyncFunctionExpression) Local 4 --- resume throw",
+    async function(a, b) { let q = await 5; var x = 3; var y = 4;
+                           try { let r = await thrower(); }
+                           catch (e) { debugger; } }, [1, 2],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Catch,
+                       debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({e: 'Exception'}, 0, exec_state);
+      CheckScopeContent({a:1,b:2,x:3,y:4, q: 5}, 1, exec_state);
+    });
+
+// Empty local scope with use of eval.
+await test(
+    "(AsyncFunctionExpression) Local 5",
+    async function() { eval(""); debugger; }, [],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({}, 0, exec_state);
+    });
+
+await test(
+    "(AsyncFunctionExpression) Local 5 --- resume normal",
+    async function() { let x = await 1; eval(""); let y = await 2;
+                       debugger; }, [],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({ x: 1, y: 2 }, 0, exec_state);
+    });
+
+await test(
+    "(AsyncFunctionExpression) Local 5 --- resume throw",
+    async function() { let x = await 1; eval("");
+                       try { let y = await thrower(); }
+                       catch (e) { debugger; } }, [],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Catch,
+                       debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({ e: 'Exception' }, 0, exec_state);
+      CheckScopeContent({ x: 1 }, 1, exec_state);
+    });
+
+// Local introducing local variable using eval.
+await test(
+    "(AsyncFunctionExpression) Local 6",
+    async function() { eval("var i = 5"); debugger; }, [],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({i:5}, 0, exec_state);
+    });
+
+await test(
+    "(AsyncFunctionExpression) Local 6 --- resume normal",
+    async function() { let x = await 1; eval("var i = 5"); let y = await 2;
+                       debugger; }, [],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({i:5, x: 1, y: 2}, 0, exec_state);
+    });
+
+await test(
+    "(AsyncFunctionExpression) Local 6 --- resume throw",
+    async function() { let x = await 1; eval("var i = 5");
+                       try { let y = await thrower(); }
+                       catch (e) { debugger; } }, [],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Catch,
+                       debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({e: 'Exception' }, 0, exec_state);
+      CheckScopeContent({i:5, x: 1}, 1, exec_state);
+    });
+
+// Local scope with parameters, local variables and local variable introduced
+// using eval.
+await test(
+    "(AsyncFunctionExpression) Local 7",
+    async function(a, b) { var x = 3; var y = 4;
+                           eval("var i = 5;"); eval("var j = 6");
+                           debugger; }, [1, 2],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 0, exec_state);
+    });
+
+await test(
+    "(AsyncFunctionExpression) Local 7 --- resume normal",
+    async function(a, b) { let z = await 7; var x = 3; var y = 4;
+                           eval("var i = 5;"); eval("var j = 6");
+                           let q = await 8;
+                           debugger; }, [1, 2],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6, z:7, q:8}, 0, exec_state);
+    });
+
+await test(
+    "(AsyncFunctionExpression) Local 7 --- resume throw",
+    async function(a, b) { let z = await 7; var x = 3; var y = 4;
+                           eval("var i = 5;"); eval("var j = 6");
+                           try { let q = await thrower(); }
+                           catch (e) { debugger; } }, [1, 2],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Catch,
+                       debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({e: 'Exception'}, 0, exec_state);
+      //CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6, z:7}, 1, exec_state);
+    });
+
+// Nested empty with blocks.
+await test(
+    "(AsyncFunctionExpression) With",
+    async function() { with ({}) { with ({}) { debugger; } } }, [],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.With,
+                       debug.ScopeType.With,
+                       debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({}, 0, exec_state);
+      CheckScopeContent({}, 1, exec_state);
+    });
+
+await test(
+    "(AsyncFunctionExpression) With --- resume normal",
+    async function() { let x = await 1; with ({}) { with ({}) {
+                       let y = await 2; debugger; } } }, [],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Block,
+                       debug.ScopeType.With,
+                       debug.ScopeType.With,
+                       debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({y:2}, 0, exec_state);
+      CheckScopeContent({}, 1, exec_state);
+      CheckScopeContent({}, 2, exec_state);
+      CheckScopeContent({x:1}, 3, exec_state);
+    });
+
+await test(
+    "(AsyncFunctionExpression) With --- resume throw",
+    async function() { let x = await 1; with ({}) { with ({}) {
+                       try { let y = await thrower(); }
+                       catch (e) { debugger; } } } }, [],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Catch,
+                       debug.ScopeType.With,
+                       debug.ScopeType.With,
+                       debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({ e: 'Exception'}, 0, exec_state);
+      CheckScopeContent({}, 1, exec_state);
+      CheckScopeContent({}, 2, exec_state);
+      CheckScopeContent({x:1}, 3, exec_state);
+    });
+
+// Simple closure formed by returning an inner function referering the outer
+// functions arguments.
+await test(
+    "(AsyncFunctionExpression) Closure 1",
+    async function(a) { return function() { debugger; return a; } }, [1],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({a:1}, 1, exec_state);
+    },
+    result => result());
+
+await test(
+    "(AsyncFunctionExpression) Closure 1 --- resume normal",
+    async function(a) { let x = await 2;
+                        return function() { debugger; return a; } }, [1],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({a:1, x: 2}, 1, exec_state);
+    },
+    result => result());
+
+await test(
+    "(AsyncFunctionExpression) Closure 1 --- resume throw",
+    async function(a) { let x = await 2;
+                        return async function() {
+                            try { await thrower(); }
+                            catch (e) { debugger; } return a; }; }, [1],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Catch,
+                       debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({e: 'Exception'}, 0, exec_state);
+      CheckScopeContent({a:1, x: 2}, 2, exec_state);
+    },
+    result => result());
+
+await test(
+    "(AsyncFunctionExpression) Catch block 1",
+    async function() { try { throw 'Exception'; } catch (e) { debugger; } }, [],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Catch,
+                       debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({e:'Exception'}, 0, exec_state);
+    });
+
+await test(
+    "(AsyncFunctionExpression) Catch block 1 --- resume normal",
+    async function() {
+      let x = await 1;
+      try { throw 'Exception'; } catch (e) { let y = await 2; debugger; } }, [],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Block,
+                       debug.ScopeType.Catch,
+                       debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({y: 2}, 0, exec_state);
+      CheckScopeContent({e:'Exception'}, 1, exec_state);
+      CheckScopeContent({x: 1}, 2, exec_state);
+    });
+
+await test(
+    "(AsyncFunctionExpression) Catch block 1 --- resume throw",
+    async function() {
+      let x = await 1;
+      try { throw 'Exception!'; } catch (e) {
+        try { let y = await thrower(); } catch (e) { debugger; } } }, [],
+    exec_state => {
+      CheckScopeChain([debug.ScopeType.Catch,
+                       debug.ScopeType.Catch,
+                       debug.ScopeType.Local,
+                       debug.ScopeType.Closure,
+                       debug.ScopeType.Script,
+                       debug.ScopeType.Global], exec_state);
+      CheckScopeContent({e:'Exception'}, 0, exec_state);
+      CheckScopeContent({e:'Exception!'}, 1, exec_state);
+      CheckScopeContent({x: 1}, 2, exec_state);
+    });
+}
+
+runTests().catch(error => {
+  print(error.stack);
+  quit(1);
+})
+
+// Check that two scope are the same.
+function assertScopeMirrorEquals(scope1, scope2) {
+  assertEquals(scope1.scopeType(), scope2.scopeType());
+  assertEquals(scope1.frameIndex(), scope2.frameIndex());
+  assertEquals(scope1.scopeIndex(), scope2.scopeIndex());
+  assertPropertiesEqual(
+      scope1.scopeObject().value(), scope2.scopeObject().value());
+}
+
+function CheckFastAllScopes(scopes, exec_state) {
+  var fast_all_scopes = exec_state.frame().allScopes(true);
+  var length = fast_all_scopes.length;
+  assertTrue(scopes.length >= length);
+  for (var i = 0; i < scopes.length && i < length; i++) {
+    var scope = fast_all_scopes[length - i - 1];
+    assertTrue(scope.isScope());
+    assertEquals(scopes[scopes.length - i - 1], scope.scopeType());
+  }
+}
+
+// Check that the scope chain contains the expected types of scopes.
+function CheckScopeChain(scopes, exec_state) {
+  var all_scopes = exec_state.frame().allScopes();
+  assertEquals(
+      scopes.length, all_scopes.length, "FrameMirror.allScopes length");
+  for (var i = 0; i < scopes.length; i++) {
+    var scope = exec_state.frame().scope(i);
+    assertTrue(scope.isScope());
+    assertEquals(scopes[i], scope.scopeType());
+    assertScopeMirrorEquals(all_scopes[i], scope);
+
+    // Check the global object when hitting the global scope.
+    if (scopes[i] == debug.ScopeType.Global) {
+      // Objects don't have same class (one is "global", other is "Object",
+      // so just check the properties directly.
+      assertPropertiesEqual(this, scope.scopeObject().value());
+    }
+  }
+  CheckFastAllScopes(scopes, exec_state);
+
+  // Get the debug command processor.
+  var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
+
+  // Send a scopes request and check the result.
+  var json;
+  var request_json = '{"seq":0,"type":"request","command":"scopes"}';
+  var response_json = dcp.processDebugJSONRequest(request_json);
+  var response = JSON.parse(response_json);
+  assertEquals(scopes.length, response.body.scopes.length);
+  for (var i = 0; i < scopes.length; i++) {
+    var scopeRef = response.body.scopes[i].object.ref;
+    assertEquals(i, response.body.scopes[i].index);
+    assertEquals(scopes[i], response.body.scopes[i].type);
+    if (scopes[i] == debug.ScopeType.Local ||
+        scopes[i] == debug.ScopeType.Script ||
+        scopes[i] == debug.ScopeType.Closure) {
+      assertTrue(response.body.scopes[i].object.ref < 0);
+    } else {
+      assertTrue(response.body.scopes[i].object.ref >= 0);
+    }
+    var found = false;
+    for (var j = 0; j < response.refs.length && !found; j++) {
+      found = response.refs[j].handle == response.body.scopes[i].object.ref;
+    }
+    assertTrue(found, `Scope object ${scopeRef} not found`);
+  }
+}
+
+// Check that the content of the scope is as expected. For functions just check
+// that there is a function.
+function CheckScopeContent(content, number, exec_state) {
+  var scope = exec_state.frame().scope(number);
+  var count = 0;
+  for (var p in content) {
+    var property_mirror = scope.scopeObject().property(p);
+    assertFalse(property_mirror.isUndefined(),
+                `property ${p} not found in scope`);
+    if (typeof(content[p]) === 'function') {
+      assertTrue(property_mirror.value().isFunction());
+    } else {
+      assertEquals(content[p], property_mirror.value().value(),
+                   `property ${p} has unexpected value`);
+    }
+    count++;
+  }
+
+  // 'arguments' and might be exposed in the local and closure scope. Just
+  // ignore this.
+  var scope_size = scope.scopeObject().properties().length;
+  if (!scope.scopeObject().property('arguments').isUndefined()) {
+    scope_size--;
+  }
+  // Skip property with empty name.
+  if (!scope.scopeObject().property('').isUndefined()) {
+    scope_size--;
+  }
+
+  if (count != scope_size) {
+    print('Names found in scope:');
+    var names = scope.scopeObject().propertyNames();
+    for (var i = 0; i < names.length; i++) {
+      print(names[i]);
+    }
+  }
+  assertEquals(count, scope_size);
+
+  // Get the debug command processor.
+  var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
+
+  // Send a scope request for information on a single scope and check the
+  // result.
+  var request_json = `{
+    "seq": 0,
+    "type": "request",
+    "command": "scope",
+    "arguments": {
+      "number": `;
+  request_json += scope.scopeIndex();
+  request_json += '}}';
+  var response_json = dcp.processDebugJSONRequest(request_json);
+  var response = JSON.parse(response_json);
+  assertEquals(scope.scopeType(), response.body.type);
+  assertEquals(number, response.body.index);
+  if (scope.scopeType() == debug.ScopeType.Local ||
+      scope.scopeType() == debug.ScopeType.Script ||
+      scope.scopeType() == debug.ScopeType.Closure) {
+    assertTrue(response.body.object.ref < 0);
+  } else {
+    assertTrue(response.body.object.ref >= 0);
+  }
+  var found = false;
+  for (var i = 0; i < response.refs.length && !found; i++) {
+    found = response.refs[i].handle == response.body.object.ref;
+  }
+  assertTrue(found, "Scope object " + response.body.object.ref + " not found");
+}
diff --git a/test/mjsunit/harmony/async-function-stacktrace.js b/test/mjsunit/harmony/async-function-stacktrace.js
new file mode 100644
index 0000000..50df44d
--- /dev/null
+++ b/test/mjsunit/harmony/async-function-stacktrace.js
@@ -0,0 +1,115 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-async-await
+
+async function test(func, funcs) {
+  try {
+    await func();
+    throw new Error("Expected " + func.toString() + " to throw");
+  } catch (e) {
+    var stack = e.stack.split('\n').
+        slice(1).
+        map(line => line.trim()).
+        map(line => line.match(/at (?:(.*) )?.*$/)[1]).
+        filter(x => typeof x === 'string' && x.length);
+
+    assertEquals(funcs, stack, `Unexpected stack trace ${e.stack}`);
+  }
+}
+
+function thrower() { throw new Error("NOPE"); }
+function reject() { return Promise.reject(new Error("NOPE")); }
+
+async function runTests() {
+  await test(async function a() {
+    throw new Error("FAIL");
+  },
+  ["a", "test", "runTests"]);
+
+  await test(async function a2() {
+    await 1;
+    throw new Error("FAIL");
+  }, ["a2"]);
+
+  await test(async function a3() {
+    await 1;
+    try { await thrower(); } catch (e) { throw new Error("FAIL"); }
+  }, ["a3"]);
+
+  await test(async function a4() {
+    await 1;
+    try { await reject(); } catch (e) { throw new Error("FAIL"); }
+  }, ["a4"]);
+
+  await test({ async b() {
+    throw new Error("FAIL");
+  }}.b,
+  ["b", "test", "runTests"]);
+
+  await test({ async b2() {
+    await 1;
+    throw new Error("FAIL");
+  }}.b2, ["b2"]);
+
+  await test({ async b3() {
+    await 1;
+    try { await thrower(); } catch (e) { throw new Error("FAIL"); }
+  } }.b3, ["b3"]);
+
+  await test({ async b4() {
+    await 1;
+    try { await reject(); } catch (e) { throw new Error("FAIL"); }
+  } }.b4, ["b4"]);
+
+  await test((new class { async c() {
+    throw new Error("FAIL");
+  } }).c,
+  ["c", "test", "runTests"]);
+
+  await test((new class { async c2() {
+    await 1;
+    throw new Error("FAIL");
+  } }).c2, ["c2"]);
+
+  await test((new class { async c3() {
+    await 1;
+    try { await thrower(); } catch (e) { throw new Error("FAIL"); }
+  } }).c3, ["c3"]);
+
+  await test((new class { async c4() {
+    await 1;
+    try { await reject(); } catch (e) { throw new Error("FAIL"); }
+  } }).c4, ["c4"]);
+
+  // TODO(caitp): `async` probably shouldn't be the inferred name for async
+  // arrow functions...
+  await test(async() => { throw new Error("FAIL") },
+  ["async", "test", "runTests"]);
+
+  await test(async() => { await 1; throw new Error("FAIL") }, ["async"]);
+
+  await test(async() => {
+    await 1;
+    try {
+      await thrower();
+    } catch (e) {
+      throw new Error("FAIL");
+    }
+  }, ["e"]); // TODO(caitp): FuncNameInferer is doing some weird stuff...
+
+  await test(async() => {
+    await 1;
+    try {
+      await reject();
+    } catch (e) {
+      throw new Error("FAIL");
+    }
+  }, ["e"]);
+}
+
+runTests().catch(e => {
+  print(e);
+  quit(1);
+});
diff --git a/test/mjsunit/harmony/debug-async-break-on-stack.js b/test/mjsunit/harmony/debug-async-break-on-stack.js
new file mode 100644
index 0000000..d3d9d8b
--- /dev/null
+++ b/test/mjsunit/harmony/debug-async-break-on-stack.js
@@ -0,0 +1,78 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug
+// Flags: --harmony-async-await --allow-natives-syntax
+
+var Debug = debug.Debug;
+
+function assertEqualsAsync(expected, run, msg) {
+  var actual;
+  var hadValue = false;
+  var hadError = false;
+  var promise = run();
+
+  if (typeof promise !== "object" || typeof promise.then !== "function") {
+    throw new MjsUnitAssertionError(
+        "Expected " + run.toString() +
+        " to return a Promise, but it returned " + promise);
+  }
+
+  promise.then(function(value) { hadValue = true; actual = value; },
+               function(error) { hadError = true; actual = error; });
+
+  assertFalse(hadValue || hadError);
+
+  %RunMicrotasks();
+
+  if (hadError) throw actual;
+
+  assertTrue(
+      hadValue, "Expected '" + run.toString() + "' to produce a value");
+
+  assertEquals(expected, actual, msg);
+}
+
+var break_count = 0;
+var exception = null;
+
+function listener(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    break_count++;
+    var line = exec_state.frame(0).sourceLineText();
+    print(line);
+    assertTrue(line.indexOf(`B${break_count}`) > 0);
+  } catch (e) {
+    exception = e;
+  }
+}
+
+
+async function g() {
+  setbreaks();
+  throw 1;  // B1
+}
+
+async function f() {
+  try {
+    await g();
+  } catch (e) {}
+  return 2;  // B2
+}
+
+function setbreaks() {
+  Debug.setListener(listener);
+  Debug.setBreakPoint(g, 2);
+  Debug.setBreakPoint(f, 4);
+}
+
+f();
+
+%RunMicrotasks();
+
+assertEqualsAsync(2, async () => break_count);
+assertEqualsAsync(null, async () => exception);
+
+Debug.setListener(null);
diff --git a/test/mjsunit/harmony/debug-async-break.js b/test/mjsunit/harmony/debug-async-break.js
new file mode 100644
index 0000000..3b6b71b
--- /dev/null
+++ b/test/mjsunit/harmony/debug-async-break.js
@@ -0,0 +1,76 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug
+// Flags: --harmony-async-await --allow-natives-syntax
+
+var Debug = debug.Debug;
+
+function assertEqualsAsync(expected, run, msg) {
+  var actual;
+  var hadValue = false;
+  var hadError = false;
+  var promise = run();
+
+  if (typeof promise !== "object" || typeof promise.then !== "function") {
+    throw new MjsUnitAssertionError(
+        "Expected " + run.toString() +
+        " to return a Promise, but it returned " + promise);
+  }
+
+  promise.then(function(value) { hadValue = true; actual = value; },
+               function(error) { hadError = true; actual = error; });
+
+  assertFalse(hadValue || hadError);
+
+  %RunMicrotasks();
+
+  if (hadError) throw actual;
+
+  assertTrue(
+      hadValue, "Expected '" + run.toString() + "' to produce a value");
+
+  assertEquals(expected, actual, msg);
+}
+
+var break_count = 0;
+var exception = null;
+
+function listener(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    break_count++;
+    var line = exec_state.frame(0).sourceLineText();
+    assertTrue(line.indexOf(`B${break_count}`) > 0);
+  } catch (e) {
+    exception = e;
+  }
+}
+
+Debug.setListener(listener);
+
+async function g() {
+  throw 1;
+}
+
+async function f() {
+  try {
+    await g();                   // B1
+  } catch (e) {}
+  assertEquals(2, break_count);  // B2
+  return 1;                      // B3
+}
+
+Debug.setBreakPoint(f, 2);
+Debug.setBreakPoint(f, 4);
+Debug.setBreakPoint(f, 5);
+
+f();
+
+%RunMicrotasks();
+
+assertEqualsAsync(3, async () => break_count);
+assertEqualsAsync(null, async () => exception);
+
+Debug.setListener(null);
diff --git a/test/mjsunit/harmony/debug-async-function-async-task-event.js b/test/mjsunit/harmony/debug-async-function-async-task-event.js
new file mode 100644
index 0000000..249f02f
--- /dev/null
+++ b/test/mjsunit/harmony/debug-async-function-async-task-event.js
@@ -0,0 +1,70 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-async-await --expose-debug-as debug --allow-natives-syntax
+
+Debug = debug.Debug;
+
+var base_id = -1;
+var exception = null;
+var expected = [
+  "enqueue #1",
+  "willHandle #1",
+  "then #1",
+  "enqueue #2",
+  "enqueue #3",
+  "didHandle #1",
+  "willHandle #2",
+  "then #2",
+  "didHandle #2",
+  "willHandle #3",
+  "enqueue #4",
+  "didHandle #3",
+  "willHandle #4",
+  "didHandle #4",
+];
+
+function assertLog(msg) {
+  print(msg);
+  assertTrue(expected.length > 0);
+  assertEquals(expected.shift(), msg);
+  if (!expected.length) {
+    Debug.setListener(null);
+  }
+}
+
+function listener(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.AsyncTaskEvent) return;
+  try {
+    if (base_id < 0)
+      base_id = event_data.id();
+    var id = event_data.id() - base_id + 1;
+    assertTrue("Promise.resolve" == event_data.name() ||
+               "PromiseResolveThenableJob" == event_data.name());
+    assertLog(event_data.type() + " #" + id);
+  } catch (e) {
+    print(e + e.stack)
+    exception = e;
+  }
+}
+
+Debug.setListener(listener);
+
+var resolver;
+var p = new Promise(function(resolve, reject) {
+  resolver = resolve;
+});
+
+async function main() {
+  await p;
+  assertLog("then #1");
+  await undefined;
+  assertLog("then #2");
+}
+main();
+resolver();
+
+%RunMicrotasks();
+
+assertNull(exception);
diff --git a/test/mjsunit/harmony/debug-async-liveedit.js b/test/mjsunit/harmony/debug-async-liveedit.js
new file mode 100644
index 0000000..c651ddb
--- /dev/null
+++ b/test/mjsunit/harmony/debug-async-liveedit.js
@@ -0,0 +1,133 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-async-await
+// Flags: --expose-debug-as debug --allow-natives-syntax --ignition-generators
+
+var Debug = debug.Debug;
+var LiveEdit = Debug.LiveEdit;
+
+unique_id = 0;
+
+var AsyncFunction = (async function(){}).constructor;
+
+function assertPromiseValue(value, promise) {
+  promise.then(resolve => {
+    went = true;
+    if (resolve !== value) {
+      print(`expected ${value} found ${resolve}`);
+      quit(1);
+    }
+  }, reject => {
+    print(`rejected ${reject}`);
+    quit(1);
+  });
+}
+
+function MakeAsyncFunction() {
+  // Prevents eval script caching.
+  unique_id++;
+  return AsyncFunction('callback',
+      "/* " + unique_id + "*/\n" +
+      "await callback();\n" +
+      "return 'Cat';\n");
+}
+
+function MakeFunction() {
+  // Prevents eval script caching.
+  unique_id++;
+  return Function('callback',
+      "/* " + unique_id + "*/\n" +
+      "callback();\n" +
+      "return 'Cat';\n");
+}
+
+// First, try MakeGenerator with no perturbations.
+(function(){
+  var asyncfn = MakeAsyncFunction();
+  function callback() {};
+  var promise = asyncfn(callback);
+  assertPromiseValue('Cat', promise);
+})();
+
+function patch(fun, from, to) {
+  function debug() {
+    var log = new Array();
+    var script = Debug.findScript(fun);
+    var pos = script.source.indexOf(from);
+    print(`pos ${pos}`);
+    try {
+      LiveEdit.TestApi.ApplySingleChunkPatch(script, pos, from.length, to,
+                                             log);
+    } finally {
+      print("Change log: " + JSON.stringify(log) + "\n");
+    }
+  }
+  %ExecuteInDebugContext(debug);
+}
+
+// Try to edit a MakeAsyncFunction while it's running, then again while it's
+// stopped.
+(function(){
+  var asyncfn = MakeAsyncFunction();
+
+  var patch_attempted = false;
+  function attempt_patch() {
+    assertFalse(patch_attempted);
+    patch_attempted = true;
+    assertThrows(function() { patch(asyncfn, "'Cat'", "'Capybara'") },
+                 LiveEdit.Failure);
+  };
+  var promise = asyncfn(attempt_patch);
+  // Patch should not succeed because there is a live async function activation
+  // on the stack.
+  assertPromiseValue("Cat", promise);
+  assertTrue(patch_attempted);
+
+  %RunMicrotasks();
+
+  // At this point one iterator is live, but closed, so the patch will succeed.
+  patch(asyncfn, "'Cat'", "'Capybara'");
+  promise = asyncfn(function(){});
+  // Patch successful.
+  assertPromiseValue("Capybara", promise);
+
+  // Patching will fail however when an async function is suspended.
+  var resolve;
+  promise = asyncfn(function(){return new Promise(function(r){resolve = r})});
+  assertThrows(function() { patch(asyncfn, "'Capybara'", "'Tapir'") },
+               LiveEdit.Failure);
+  resolve();
+  assertPromiseValue("Capybara", promise);
+
+  // Try to patch functions with activations inside and outside async
+  // function activations.  We should succeed in the former case, but not in the
+  // latter.
+  var fun_outside = MakeFunction();
+  var fun_inside = MakeFunction();
+  var fun_patch_attempted = false;
+  var fun_patch_restarted = false;
+  function attempt_fun_patches() {
+    if (fun_patch_attempted) {
+      assertFalse(fun_patch_restarted);
+      fun_patch_restarted = true;
+      return;
+    }
+    fun_patch_attempted = true;
+    // Patching outside an async function activation must fail.
+    assertThrows(function() { patch(fun_outside, "'Cat'", "'Cobra'") },
+                 LiveEdit.Failure);
+    // Patching inside an async function activation may succeed.
+    patch(fun_inside, "'Cat'", "'Koala'");
+  }
+  promise = asyncfn(function() { return fun_inside(attempt_fun_patches) });
+  assertEquals('Cat',
+               fun_outside(function () {
+                 assertPromiseValue('Capybara', promise);
+                 assertTrue(fun_patch_restarted);
+                 assertTrue(fun_inside.toString().includes("'Koala'"));
+               }));
+})();
+
+%RunMicrotasks();
diff --git a/test/mjsunit/harmony/function-name.js b/test/mjsunit/harmony/function-name.js
deleted file mode 100644
index 66a69e0..0000000
--- a/test/mjsunit/harmony/function-name.js
+++ /dev/null
@@ -1,372 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// Flags: --harmony-function-name
-
-(function testVariableDeclarationsFunction() {
-  'use strict';
-  var a = function(){};
-  assertEquals('a', a.name);
-  let b = () => {};
-  assertEquals('b', b.name);
-  const c = ((function(){}));
-  assertEquals('c', c.name);
-
-  var x = function(){}, y = () => {}, z = function withName() {};
-  assertEquals('x', x.name);
-  assertEquals('y', y.name);
-  assertEquals('withName', z.name);
-})();
-
-(function testVariableDeclarationsClass() {
-  'use strict';
-  var a = class {};
-  assertEquals('a', a.name);
-  let b = ((class {}));
-  assertEquals('b', b.name);
-  // Should not overwrite name property.
-  const c = class { static name() { } }
-  assertEquals('function', typeof c.name);
-
-  var x = class {}, y = class NamedClass {};
-  assertEquals('x', x.name);
-  assertEquals('NamedClass', y.name);
-})();
-
-(function testObjectProperties() {
-  'use strict';
-  var obj = {
-    a: function() {},
-    b: () => {},
-    c() { },
-    get d() { },
-    set d(val) { },
-    x: function withName() { },
-    y: class { },
-    z: class ClassName { },
-    42: function() {},
-    4.2: function() {},
-    __proto__: function() {},
-  };
-
-  assertEquals('a', obj.a.name);
-  assertEquals('b', obj.b.name);
-  assertEquals('c', obj.c.name);
-  var dDescriptor = Object.getOwnPropertyDescriptor(obj, 'd');
-  assertEquals('get d', dDescriptor.get.name);
-  assertEquals('set d', dDescriptor.set.name);
-  assertEquals('withName', obj.x.name);
-  assertEquals('y', obj.y.name);
-  assertEquals('ClassName', obj.z.name);
-  assertEquals('42', obj[42].name);
-  assertEquals('4.2', obj[4.2].name);
-  assertEquals('', obj.__proto__.name);
-})();
-
-(function testClassProperties() {
-  'use strict';
-  class C {
-    a() { }
-    static b() { }
-    get c() { }
-    set c(val) { }
-    42() { }
-    static 43() { }
-    get 44() { }
-    set 44(val) { }
-  };
-
-  assertEquals('a', C.prototype.a.name);
-  assertEquals('b', C.b.name);
-  var descriptor = Object.getOwnPropertyDescriptor(C.prototype, 'c');
-  assertEquals('get c', descriptor.get.name);
-  assertEquals('set c', descriptor.set.name);
-  assertEquals('42', C.prototype[42].name);
-  assertEquals('43', C[43].name);
-  var descriptor = Object.getOwnPropertyDescriptor(C.prototype, '44');
-  assertEquals('get 44', descriptor.get.name);
-  assertEquals('set 44', descriptor.set.name);
-})();
-
-(function testComputedProperties() {
-  'use strict';
-  var a = 'a';
-  var b = 'b';
-  var sym1 = Symbol('1');
-  var sym2 = Symbol('2');
-  var sym3 = Symbol('3');
-  var symNoDescription = Symbol();
-  var obj = {
-    [a]: function() {},
-    [sym1]: function() {},
-    [sym2]: function withName() {},
-    [symNoDescription]: function() {},
-
-    get [sym3]() {},
-    set [b](val) {},
-  };
-
-  assertEquals('a', obj[a].name);
-  assertEquals('[1]', obj[sym1].name);
-  assertEquals('withName', obj[sym2].name);
-  assertEquals('', obj[symNoDescription].name);
-
-  assertEquals('get [3]', Object.getOwnPropertyDescriptor(obj, sym3).get.name);
-  assertEquals('set b', Object.getOwnPropertyDescriptor(obj, 'b').set.name);
-
-  var objMethods = {
-    [a]() {},
-    [sym1]() {},
-    [symNoDescription]: function() {},
-  };
-
-  assertEquals('a', objMethods[a].name);
-  assertEquals('[1]', objMethods[sym1].name);
-  assertEquals('', objMethods[symNoDescription].name);
-
-  class C {
-    [a]() { }
-    [sym1]() { }
-    static [sym2]() { }
-    [symNoDescription]() { }
-
-    get [sym3]() { }
-    static set [b](val) { }
-  }
-
-  assertEquals('a', C.prototype[a].name);
-  assertEquals('[1]', C.prototype[sym1].name);
-  assertEquals('[2]', C[sym2].name);
-  assertEquals('', C.prototype[symNoDescription].name);
-
-  assertEquals('get [3]', Object.getOwnPropertyDescriptor(C.prototype, sym3).get.name);
-  assertEquals('set b', Object.getOwnPropertyDescriptor(C, 'b').set.name);
-})();
-
-
-(function testAssignment() {
-  var basicFn, arrowFn, generatorFn, classLit;
-
-  basicFn = function() { return true; };
-  assertEquals('basicFn', basicFn.name);
-  var basicFn2 = basicFn;
-  assertEquals('basicFn', basicFn2.name);
-  basicFn = function functionWithName() { };
-  assertEquals("functionWithName", basicFn.name);
-
-  arrowFn = x => x;
-  assertEquals('arrowFn', arrowFn.name);
-  var arrowFn2 = arrowFn;
-  assertEquals('arrowFn', arrowFn2.name);
-
-  generatorFn = function*() { yield true; };
-  assertEquals('generatorFn', generatorFn.name);
-  var generatorFn2 = generatorFn;
-  assertEquals('generatorFn', generatorFn2.name);
-  generatorFn = function* generatorWithName() { };
-  assertEquals("generatorWithName", generatorFn.name);
-
-  classLit = class { constructor() {} };
-  assertEquals('classLit', classLit.name);
-  var classLit2 = classLit;
-  assertEquals('classLit', classLit2.name);
-  classLit = class classWithName { constructor() {} };
-  assertEquals('classWithName', classLit.name);
-  classLit = class { constructor() {} static name() {} };
-  assertEquals('function', typeof classLit.name);
-  classLit = class { constructor() {} static get name() { return true; } };
-  assertTrue(classLit.name);
-  classLit = class { constructor() {} static ['name']() {} };
-  assertEquals('function', typeof classLit.name);
-  classLit = class { constructor() {} static get ['name']() { return true; } };
-  assertTrue(classLit.name);
-})();
-
-(function testObjectBindingPattern() {
-  var {
-    a = function() {},
-    b = () => {},
-    x = function withName() { },
-    y = class { },
-    z = class ClassName { },
-    q = class { static name() { return 42 } },
-    foo: bar = function() {},
-    inParens = (() => {}),
-    inManyParens = ((((() => {})))),
-  } = {};
-  assertEquals('a', a.name);
-  assertEquals('b', b.name);
-  assertEquals('withName', x.name);
-  assertEquals('y', y.name);
-  assertEquals('ClassName', z.name);
-  assertEquals('function', typeof q.name);
-  assertEquals('bar', bar.name);
-  assertEquals('inParens', inParens.name)
-  assertEquals('inManyParens', inManyParens.name)
-})();
-
-(function testArrayBindingPattern() {
-  var [
-    a = function() {},
-    b = () => {},
-    x = function withName() { },
-    y = class { },
-    z = class ClassName { },
-    q = class { static name() { return 42 } },
-    inParens = (() => {}),
-    inManyParens = ((((() => {})))),
-  ] = [];
-  assertEquals('a', a.name);
-  assertEquals('b', b.name);
-  assertEquals('withName', x.name);
-  assertEquals('y', y.name);
-  assertEquals('ClassName', z.name);
-  assertEquals('function', typeof q.name);
-  assertEquals('inParens', inParens.name)
-  assertEquals('inManyParens', inManyParens.name)
-})();
-
-(function testObjectAssignmentPattern() {
-  var a, b, x, y, z, q;
-  ({
-    a = function() {},
-    b = () => {},
-    x = function withName() { },
-    y = class { },
-    z = class ClassName { },
-    q = class { static name() { return 42 } },
-    foo: bar = function() {},
-    inParens = (() => {}),
-    inManyParens = ((((() => {})))),
-  } = {});
-  assertEquals('a', a.name);
-  assertEquals('b', b.name);
-  assertEquals('withName', x.name);
-  assertEquals('y', y.name);
-  assertEquals('ClassName', z.name);
-  assertEquals('function', typeof q.name);
-  assertEquals('bar', bar.name);
-  assertEquals('inParens', inParens.name)
-  assertEquals('inManyParens', inManyParens.name)
-})();
-
-(function testArrayAssignmentPattern() {
-  var a, b, x, y, z, q;
-  [
-    a = function() {},
-    b = () => {},
-    x = function withName() { },
-    y = class { },
-    z = class ClassName { },
-    q = class { static name() { return 42 } },
-    inParens = (() => {}),
-    inManyParens = ((((() => {})))),
-  ] = [];
-  assertEquals('a', a.name);
-  assertEquals('b', b.name);
-  assertEquals('withName', x.name);
-  assertEquals('y', y.name);
-  assertEquals('ClassName', z.name);
-  assertEquals('function', typeof q.name);
-  assertEquals('inParens', inParens.name)
-  assertEquals('inManyParens', inManyParens.name)
-})();
-
-(function testParameterDestructuring() {
-  (function({ a = function() {},
-              b = () => {},
-              x = function withName() { },
-              y = class { },
-              z = class ClassName { },
-              q = class { static name() { return 42 } },
-              foo: bar = function() {},
-              inParens = (() => {}),
-              inManyParens = ((((() => {})))) }) {
-    assertEquals('a', a.name);
-    assertEquals('b', b.name);
-    assertEquals('withName', x.name);
-    assertEquals('y', y.name);
-    assertEquals('ClassName', z.name);
-    assertEquals('function', typeof q.name);
-    assertEquals('bar', bar.name);
-    assertEquals('inParens', inParens.name)
-    assertEquals('inManyParens', inManyParens.name)
-  })({});
-
-  (function([ a = function() {},
-              b = () => {},
-              x = function withName() { },
-              y = class { },
-              z = class ClassName { },
-              q = class { static name() { return 42 } },
-              inParens = (() => {}),
-              inManyParens = ((((() => {})))) ]) {
-    assertEquals('a', a.name);
-    assertEquals('b', b.name);
-    assertEquals('withName', x.name);
-    assertEquals('y', y.name);
-    assertEquals('ClassName', z.name);
-    assertEquals('function', typeof q.name);
-    assertEquals('inParens', inParens.name)
-    assertEquals('inManyParens', inManyParens.name)
-  })([]);
-})();
-
-(function testDefaultParameters() {
-  (function(a = function() {},
-            b = () => {},
-            x = function withName() { },
-            y = class { },
-            z = class ClassName { },
-            q = class { static name() { return 42 } },
-            inParens = (() => {}),
-            inManyParens = ((((() => {}))))) {
-    assertEquals('a', a.name);
-    assertEquals('b', b.name);
-    assertEquals('withName', x.name);
-    assertEquals('y', y.name);
-    assertEquals('ClassName', z.name);
-    assertEquals('function', typeof q.name);
-    assertEquals('inParens', inParens.name)
-    assertEquals('inManyParens', inManyParens.name)
-  })();
-})();
-
-(function testComputedNameNotShared() {
-  function makeClass(propName) {
-    return class {
-      static [propName]() {}
-    }
-  }
-
-  var sym1 = Symbol('1');
-  var sym2 = Symbol('2');
-  var class1 = makeClass(sym1);
-  assertEquals('[1]', class1[sym1].name);
-  var class2 = makeClass(sym2);
-  assertEquals('[2]', class2[sym2].name);
-  assertEquals('[1]', class1[sym1].name);
-})();
-
-
-(function testComputedNamesOnlyAppliedSyntactically() {
-  function factory() { return () => {}; }
-
-  var obj = { ['foo']: factory() };
-  assertEquals('', obj.foo.name);
-})();
-
-
-(function testNameNotReflectedInToString() {
-  var f = function() {};
-  var g = function*() {};
-  var obj = {
-    ['h']: function() {},
-    i: () => {}
-  };
-  assertEquals('function () {}', f.toString());
-  assertEquals('function* () {}', g.toString());
-  assertEquals('function () {}', obj.h.toString());
-  assertEquals('() => {}', obj.i.toString());
-})();
diff --git a/test/mjsunit/harmony/generators-turbo.js b/test/mjsunit/harmony/generators-turbo.js
new file mode 100644
index 0000000..23913e4
--- /dev/null
+++ b/test/mjsunit/harmony/generators-turbo.js
@@ -0,0 +1,655 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --ignition --ignition-generators --harmony-do-expressions
+// Flags: --allow-natives-syntax --turbo --turbo-from-bytecode
+
+
+// This file is identical to mjsunit/harmony/generators.js, except for its Flags
+// lines. The purpose is to explicitly mention --turbo-from-bytecode such that
+// Clusterfuzz can thoroughly test the new generators implementation.
+
+
+function MaybeOptimizeOrDeoptimize(f) {
+  let x = Math.random();  // --random-seed makes this deterministic
+  if (x <= 0.33) {
+    %OptimizeFunctionOnNextCall(f);
+  } else if (x <= 0.66) {
+    %DeoptimizeFunction(f);
+  }
+}
+
+function Next(generator, ...args) {
+  MaybeOptimizeOrDeoptimize(%GeneratorGetFunction(generator));
+  return generator.next(...args);
+}
+
+function Return(generator, ...args) {
+  MaybeOptimizeOrDeoptimize(%GeneratorGetFunction(generator));
+  return generator.return(...args);
+}
+
+function Throw(generator, ...args) {
+  MaybeOptimizeOrDeoptimize(%GeneratorGetFunction(generator));
+  return generator.throw(...args);
+}
+
+
+{ // yield in try-catch
+
+  let g = function*() {
+    try {yield 1} catch (error) {assertEquals("caught", error)}
+  };
+
+  assertThrowsEquals(() => Throw(g(), "not caught"), "not caught");
+
+  {
+    let x = g();
+    assertEquals({value: 1, done: false}, Next(x));
+    assertEquals({value: undefined, done: true}, Throw(x, "caught"));
+  }
+
+  {
+    let x = g();
+    assertEquals({value: 1, done: false}, Next(x));
+    assertEquals({value: undefined, done: true}, Next(x));
+    assertThrowsEquals(() => Throw(x, "not caught"), "not caught");
+  }
+}
+
+
+{ // return that doesn't close
+  let g = function*() { try {return 42} finally {yield 43} };
+
+  {
+    let x = g();
+    assertEquals({value: 43, done: false}, Next(x));
+    assertEquals({value: 42, done: true}, Next(x));
+  }
+}
+
+
+{ // return that doesn't close
+  let x;
+  let g = function*() { try {return 42} finally {Throw(x, 666)} };
+
+  {
+    x = g();
+    assertThrows(() => Next(x), TypeError);  // still executing
+  }
+}
+
+
+{ // yield in try-finally, finally clause performs return
+
+  let g = function*() { try {yield 42} finally {return 13} };
+
+  { // "return" closes at suspendedStart
+    let x = g();
+    assertEquals({value: 666, done: true}, Return(x, 666));
+    assertEquals({value: undefined, done: true}, Next(x, 42));
+    assertThrowsEquals(() => Throw(x, 43), 43);
+    assertEquals({value: 42, done: true}, Return(x, 42));
+  }
+
+  { // "throw" closes at suspendedStart
+    let x = g();
+    assertThrowsEquals(() => Throw(x, 666), 666);
+    assertEquals({value: undefined, done: true}, Next(x, 42));
+    assertEquals({value: 43, done: true}, Return(x, 43));
+    assertThrowsEquals(() => Throw(x, 44), 44);
+  }
+
+  { // "next" closes at suspendedYield
+    let x = g();
+    assertEquals({value: 42, done: false}, Next(x));
+    assertEquals({value: 13, done: true}, Next(x, 666));
+    assertEquals({value: undefined, done: true}, Next(x, 666));
+    assertThrowsEquals(() => Throw(x, 666), 666);
+  }
+
+  { // "return" closes at suspendedYield
+    let x = g();
+    assertEquals({value: 42, done: false}, Next(x));
+    assertEquals({value: 13, done: true}, Return(x, 666));
+    assertEquals({value: undefined, done: true}, Next(x, 666));
+    assertEquals({value: 666, done: true}, Return(x, 666));
+  }
+
+  { // "throw" closes at suspendedYield
+    let x = g();
+    assertEquals({value: 42, done: false}, Next(x));
+    assertEquals({value: 13, done: true}, Throw(x, 666));
+    assertThrowsEquals(() => Throw(x, 666), 666);
+    assertEquals({value: undefined, done: true}, Next(x, 666));
+  }
+}
+
+
+{ // yield in try-finally, finally clause doesn't perform return
+
+  let g = function*() { try {yield 42} finally {13} };
+
+  { // "return" closes at suspendedStart
+    let x = g();
+    assertEquals({value: 666, done: true}, Return(x, 666));
+    assertEquals({value: undefined, done: true}, Next(x, 42));
+    assertThrowsEquals(() => Throw(x, 43), 43);
+    assertEquals({value: 42, done: true}, Return(x, 42));
+  }
+
+  { // "throw" closes at suspendedStart
+    let x = g();
+    assertThrowsEquals(() => Throw(x, 666), 666);
+    assertEquals({value: undefined, done: true}, Next(x, 42));
+    assertEquals({value: 43, done: true}, Return(x, 43));
+    assertThrowsEquals(() => Throw(x, 44), 44);
+  }
+
+  { // "next" closes at suspendedYield
+    let x = g();
+    assertEquals({value: 42, done: false}, Next(x));
+    assertEquals({value: undefined, done: true}, Next(x, 666));
+    assertEquals({value: undefined, done: true}, Next(x, 666));
+    assertThrowsEquals(() => Throw(x, 666), 666);
+    assertEquals({value: 42, done: true}, Return(x, 42));
+  }
+
+  { // "return" closes at suspendedYield
+    let x = g();
+    assertEquals({value: 42, done: false}, Next(x));
+    assertEquals({value: 666, done: true}, Return(x, 666));
+    assertEquals({value: undefined, done: true}, Next(x, 666));
+    assertThrowsEquals(() => Throw(x, 44), 44);
+    assertEquals({value: 42, done: true}, Return(x, 42));
+  }
+
+  { // "throw" closes at suspendedYield
+    let x = g();
+    assertEquals({value: 42, done: false}, Next(x));
+    assertThrowsEquals(() => Throw(x, 666), 666);
+    assertEquals({value: undefined, done: true}, Next(x, 666));
+    assertThrowsEquals(() => Throw(x, 666), 666);
+    assertEquals({value: 42, done: true}, Return(x, 42));
+  }
+}
+
+
+{ // yield in try-finally, finally clause yields and performs return
+
+  let g = function*() { try {yield 42} finally {yield 43; return 13} };
+
+  {
+    let x = g();
+    assertEquals({value: 42, done: false}, Next(x));
+    assertEquals({value: 43, done: false}, Return(x, 666));
+    assertEquals({value: 13, done: true}, Next(x));
+    assertEquals({value: 666, done: true}, Return(x, 666));
+  }
+
+  {
+    let x = g();
+    assertEquals({value: 666, done: true}, Return(x, 666));
+    assertEquals({value: undefined, done: true}, Next(x));
+    assertEquals({value: 666, done: true}, Return(x, 666));
+  }
+}
+
+
+{ // yield in try-finally, finally clause yields and doesn't perform return
+
+  let g = function*() { try {yield 42} finally {yield 43; 13} };
+
+  {
+    let x = g();
+    assertEquals({value: 42, done: false}, Next(x));
+    assertEquals({value: 43, done: false}, Return(x, 666));
+    assertEquals({value: 666, done: true}, Next(x));
+    assertEquals({value: 5, done: true}, Return(x, 5));
+  }
+
+  {
+    let x = g();
+    assertEquals({value: 666, done: true}, Return(x, 666));
+    assertEquals({value: undefined, done: true}, Next(x));
+    assertEquals({value: 666, done: true}, Return(x, 666));
+  }
+}
+
+
+{ // yield*, finally clause performs return
+
+  let h = function*() { try {yield 42} finally {yield 43; return 13} };
+  let g = function*() { yield 1; yield yield* h(); };
+
+  {
+    let x = g();
+    assertEquals({value: 1, done: false}, Next(x));
+    assertEquals({value: 42, done: false}, Next(x));
+    assertEquals({value: 43, done: false}, Next(x, 666));
+    assertEquals({value: 13, done: false}, Next(x));
+    assertEquals({value: undefined, done: true}, Next(x));
+  }
+
+  {
+    let x = g();
+    assertEquals({value: 1, done: false}, Next(x));
+    assertEquals({value: 42, done: false}, Next(x));
+    assertEquals({value: 43, done: false}, Return(x, 666));
+    assertEquals({value: 13, done: false}, Next(x));
+    assertEquals({value: undefined, done: true}, Next(x));
+  }
+
+  {
+    let x = g();
+    assertEquals({value: 1, done: false}, Next(x));
+    assertEquals({value: 42, done: false}, Next(x));
+    assertEquals({value: 43, done: false}, Throw(x, 666));
+    assertEquals({value: 13, done: false}, Next(x));
+    assertEquals({value: undefined, done: true}, Next(x));
+  }
+}
+
+
+{ // yield*, finally clause does not perform return
+
+  let h = function*() { try {yield 42} finally {yield 43; 13} };
+  let g = function*() { yield 1; yield yield* h(); };
+
+  {
+    let x = g();
+    assertEquals({value: 1, done: false}, Next(x));
+    assertEquals({value: 42, done: false}, Next(x));
+    assertEquals({value: 43, done: false}, Next(x, 666));
+    assertEquals({value: undefined, done: false}, Next(x));
+    assertEquals({value: undefined, done: true}, Next(x));
+  }
+
+  {
+    let x = g();
+    assertEquals({value: 1, done: false}, Next(x));
+    assertEquals({value: 42, done: false}, Next(x));
+    assertEquals({value: 43, done: false}, Return(x, 44));
+    assertEquals({value: 44, done: false}, Next(x));
+    assertEquals({value: undefined, done: true}, Next(x));
+  }
+
+  {
+    let x = g();
+    assertEquals({value: 1, done: false}, Next(x));
+    assertEquals({value: 42, done: false}, Next(x));
+    assertEquals({value: 43, done: false}, Throw(x, 666));
+    assertThrowsEquals(() => Next(x), 666);
+  }
+}
+
+
+{ // yield*, .return argument is final result
+
+  function* inner() {
+    yield 2;
+  }
+
+  function* g() {
+    yield 1;
+    return yield* inner();
+  }
+
+  {
+    let x = g();
+    assertEquals({value: 1, done: false}, Next(x));
+    assertEquals({value: 2, done: false}, Next(x));
+    assertEquals({value: 42, done: true}, Return(x, 42));
+  }
+}
+
+
+// More or less random tests from here on.
+
+
+{
+  function* foo() { }
+  let g = foo();
+  assertEquals({value: undefined, done: true}, Next(g));
+  assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+  function* foo() { return new.target }
+  let g = foo();
+  assertEquals({value: undefined, done: true}, Next(g));
+  assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+  function* foo() { throw 666; return 42}
+  let g = foo();
+  assertThrowsEquals(() => Next(g), 666);
+  assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+  function* foo(a) { return a; }
+  let g = foo(42);
+  assertEquals({value: 42, done: true}, Next(g));
+  assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+  function* foo(a) { a.iwashere = true; return a; }
+  let x = {};
+  let g = foo(x);
+  assertEquals({value: {iwashere: true}, done: true}, Next(g));
+  assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+  let a = 42;
+  function* foo() { return a; }
+  let g = foo();
+  assertEquals({value: 42, done: true}, Next(g));
+  assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+  let a = 40;
+  function* foo(b) { return a + b; }
+  let g = foo(2);
+  assertEquals({value: 42, done: true}, Next(g));
+  assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+  let a = 40;
+  function* foo(b) { a--; b++; return a + b; }
+  let g = foo(2);
+  assertEquals({value: 42, done: true}, Next(g));
+  assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+  let g;
+  function* foo() { Next(g) }
+  g = foo();
+  assertThrows(() => Next(g), TypeError);
+  assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+  function* foo() { yield 2; yield 3; yield 4 }
+  g = foo();
+  assertEquals({value: 2, done: false}, Next(g));
+  assertEquals({value: 3, done: false}, Next(g));
+  assertEquals({value: 4, done: false}, Next(g));
+  assertEquals({value: undefined, done: true}, Next(g));
+  assertEquals({value: undefined, done: true}, Next(g));
+}
+
+
+{
+  function* foo() { yield 2; if (true) { yield 3 }; yield 4 }
+  g = foo();
+  assertEquals({value: 2, done: false}, Next(g));
+  assertEquals({value: 3, done: false}, Next(g));
+  assertEquals({value: 4, done: false}, Next(g));
+  assertEquals({value: undefined, done: true}, Next(g));
+  assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+  function* foo() { yield 2; if (true) { yield 3; yield 4 } }
+  g = foo();
+  assertEquals({value: 2, done: false}, Next(g));
+  assertEquals({value: 3, done: false}, Next(g));
+  assertEquals({value: 4, done: false}, Next(g));
+  assertEquals({value: undefined, done: true}, Next(g));
+  assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+  function* foo() { yield 2; if (false) { yield 3 }; yield 4 }
+  g = foo();
+  assertEquals({value: 2, done: false}, Next(g));
+  assertEquals({value: 4, done: false}, Next(g));
+  assertEquals({value: undefined, done: true}, Next(g));
+  assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+  function* foo() { yield 2; while (true) { yield 3 }; yield 4 }
+  g = foo();
+  assertEquals({value: 2, done: false}, Next(g));
+  assertEquals({value: 3, done: false}, Next(g));
+  assertEquals({value: 3, done: false}, Next(g));
+  assertEquals({value: 3, done: false}, Next(g));
+  assertEquals({value: 3, done: false}, Next(g));
+}
+
+{
+  function* foo() { yield 2; (yield 3) + 42; yield 4 }
+  g = foo();
+  assertEquals({value: 2, done: false}, Next(g));
+  assertEquals({value: 3, done: false}, Next(g));
+  assertEquals({value: 4, done: false}, Next(g));
+}
+
+{
+  function* foo() { yield 2; (do {yield 3}) + 42; yield 4 }
+  g = foo();
+  assertEquals({value: 2, done: false}, Next(g));
+  assertEquals({value: 3, done: false}, Next(g));
+  assertEquals({value: 4, done: false}, Next(g));
+}
+
+{
+  function* foo() { yield 2; return (yield 3) + 42; yield 4 }
+  g = foo();
+  assertEquals({value: 2, done: false}, Next(g));
+  assertEquals({value: 3, done: false}, Next(g));
+  assertEquals({value: 42, done: true}, Next(g, 0));
+  assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+  let x = 42;
+  function* foo() {
+    yield x;
+    for (let x in {a: 1, b: 2}) {
+      let i = 2;
+      yield x;
+      yield i;
+      do {
+        yield i;
+      } while (i-- > 0);
+    }
+    yield x;
+    return 5;
+  }
+  g = foo();
+  assertEquals({value: 42, done: false}, Next(g));
+  assertEquals({value: 'a', done: false}, Next(g));
+  assertEquals({value: 2, done: false}, Next(g));
+  assertEquals({value: 2, done: false}, Next(g));
+  assertEquals({value: 1, done: false}, Next(g));
+  assertEquals({value: 0, done: false}, Next(g));
+  assertEquals({value: 'b', done: false}, Next(g));
+  assertEquals({value: 2, done: false}, Next(g));
+  assertEquals({value: 2, done: false}, Next(g));
+  assertEquals({value: 1, done: false}, Next(g));
+  assertEquals({value: 0, done: false}, Next(g));
+  assertEquals({value: 42, done: false}, Next(g));
+  assertEquals({value: 5, done: true}, Next(g));
+}
+
+{
+  let a = 3;
+  function* foo() {
+    let b = 4;
+    yield 1;
+    { let c = 5; yield 2; yield a; yield b; yield c; }
+  }
+  g = foo();
+  assertEquals({value: 1, done: false}, Next(g));
+  assertEquals({value: 2, done: false}, Next(g));
+  assertEquals({value: 3, done: false}, Next(g));
+  assertEquals({value: 4, done: false}, Next(g));
+  assertEquals({value: 5, done: false}, Next(g));
+  assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+  function* foo() {
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+    yield 42;
+  }
+  g = foo();
+  for (let i = 0; i < 100; ++i) {
+    assertEquals({value: 42, done: false}, i%25 === 0 ? Next(g) : g.next());
+  }
+  assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+  function* foo() {
+    for (let i = 0; i < 3; ++i) {
+      let j = 0
+      yield i;
+      do {
+        yield (i + 10);
+      } while (++j < 2);
+    }
+  }
+  g = foo();
+  assertEquals({value: 0, done: false}, Next(g));
+  assertEquals({value: 10, done: false}, Next(g));
+  assertEquals({value: 10, done: false}, Next(g));
+  assertEquals({value: 1, done: false}, Next(g));
+  assertEquals({value: 11, done: false}, Next(g));
+  assertEquals({value: 11, done: false}, Next(g));
+  assertEquals({value: 2, done: false}, Next(g));
+  assertEquals({value: 12, done: false}, Next(g));
+  assertEquals({value: 12, done: false}, Next(g));
+  assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+  let foo = function*() {
+    while (true) {
+      if (true || false) yield 42;
+      continue;
+    }
+  }
+  g = foo();
+  assertEquals({value: 42, done: false}, Next(g));
+  assertEquals({value: 42, done: false}, Next(g));
+  assertEquals({value: 42, done: false}, Next(g));
+}
+
+{
+  let foo = function*() {
+    yield* (function*() { yield 42; }());
+    assertUnreachable();
+  }
+  g = foo();
+  assertEquals({value: 42, done: false}, Next(g));
+  assertEquals({value: 23, done: true}, Return(g, 23));
+}
diff --git a/test/mjsunit/harmony/generators.js b/test/mjsunit/harmony/generators.js
index 895a248..eb4e51e 100644
--- a/test/mjsunit/harmony/generators.js
+++ b/test/mjsunit/harmony/generators.js
@@ -648,15 +648,3 @@
   assertEquals({value: 42, done: false}, Next(g));
   assertEquals({value: 23, done: true}, Return(g, 23));
 }
-
-{
-  let iterable = {
-    [Symbol.iterator]() {
-      return { next() { return {} } };
-    }
-  };
-  let foo = function*() { yield* iterable };
-  g = foo();
-  g.next();
-  assertThrows(() => Throw(g), TypeError);
-}
diff --git a/test/mjsunit/harmony/instanceof-es6.js b/test/mjsunit/harmony/instanceof-es6.js
deleted file mode 100644
index 4971c9c..0000000
--- a/test/mjsunit/harmony/instanceof-es6.js
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-instanceof
-
-// Make sure it's an error if @@hasInstance isn't a function.
-(function() {
-  var F = {};
-  F[Symbol.hasInstance] = null;
-  assertThrows(function() { 0 instanceof F; }, TypeError);
-})();
-
-// Make sure the result is coerced to boolean.
-(function() {
-  var F = {};
-  F[Symbol.hasInstance] = function() { return undefined; };
-  assertEquals(0 instanceof F, false);
-  F[Symbol.hasInstance] = function() { return null; };
-  assertEquals(0 instanceof F, false);
-  F[Symbol.hasInstance] = function() { return true; };
-  assertEquals(0 instanceof F, true);
-})();
-
-// Make sure if @@hasInstance throws, we catch it.
-(function() {
-  var F = {};
-  F[Symbol.hasInstance] = function() { throw new Error("always throws"); }
-  try {
-    0 instanceof F;
-  } catch (e) {
-    assertEquals(e.message, "always throws");
-  }
-})();
-
-// @@hasInstance works for bound functions.
-(function() {
-  var BC = function() {};
-  var bc = new BC();
-  var bound = BC.bind();
-  assertEquals(bound[Symbol.hasInstance](bc), true);
-  assertEquals(bound[Symbol.hasInstance]([]), false);
-})();
-
-// if OrdinaryHasInstance is passed a non-callable receiver, return false.
-assertEquals(Function.prototype[Symbol.hasInstance].call(Array, []), true);
-assertEquals(Function.prototype[Symbol.hasInstance].call({}, {}), false);
-
-// OrdinaryHasInstance passed a non-object argument returns false.
-assertEquals(Function.prototype[Symbol.hasInstance].call(Array, 0), false);
-
-// Cannot assign to @@hasInstance with %FunctionPrototype%.
-(function() {
-  "use strict";
-  function F() {}
-  assertThrows(function() { F[Symbol.hasInstance] = (v) => v }, TypeError);
-})();
-
-// Check correct invocation of @@hasInstance handler on function instance.
-(function() {
-  function F() {}
-  var counter = 0;
-  var proto = Object.getPrototypeOf(F);
-  Object.setPrototypeOf(F, null);
-  F[Symbol.hasInstance] = function(v) { ++counter; return true };
-  Object.setPrototypeOf(F, proto);
-  assertTrue(1 instanceof F);
-  assertEquals(1, counter);
-})();
diff --git a/test/mjsunit/harmony/iterator-close.js b/test/mjsunit/harmony/iterator-close.js
deleted file mode 100644
index 03cdeac..0000000
--- a/test/mjsunit/harmony/iterator-close.js
+++ /dev/null
@@ -1,1372 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-iterator-close
-
-
-function* g() { yield 42; return 88 };
-
-
-// Return method is "undefined".
-{
-  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 (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())
-  );
-}
-
-
-// Return method is not callable.
-{
-  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 (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);
-}
-
-
-// Return method does not return an object.
-{
-  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);
-
-
-  // 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; }
-  }, 666);
-
-  assertThrowsEquals(() => {
-    for (const x of g()) { throw 666; }
-  }, 666);
-
-  assertThrowsEquals(() => {
-    for (x of g()) { throw 666; }
-  }, 666);
-
-
-  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 (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);
-}
-
-
-// Return method returns an object.
-{
-  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; }
-  }, 42);
-  assertEquals([[]], log);
-
-  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; }
-  })());
-  assertEquals([[]], log);
-
-  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;
-  }
-}
-
-
-// Return method throws.
-{
-  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; }
-  }, 23);
-  assertEquals([[]], log);
-
-  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; }
-  }, 42);
-  assertEquals([[]], log);
-
-  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; }
-  }, 23);
-  assertEquals([[]], log);
-
-  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);
-}
-
-
-// Next method throws.
-{
-  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);
-
-  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);
-
-  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);
-
-  assertThrowsEquals(() => {
-    var [...x] = g();
-  }, 666);
-
-  assertThrowsEquals(() => {
-    let [...x] = g();
-  }, 666);
-
-  assertThrowsEquals(() => {
-    const [...x] = g();
-  }, 666);
-
-  assertThrowsEquals(() => {
-    [...x] = g();
-  }, 666);
-
-  assertThrowsEquals(() => {
-    (([...x]) => x)(g());
-  }, 666);
-}
-
-
-// Nested loops.
-{
-  function* g1() { yield 1; yield 2; throw 3; }
-  function* g2() { yield -1; yield -2; throw -3; }
-
-  assertDoesNotThrow(() => {
-    for (let x of g1()) {
-      for (let y of g2()) {
-        if (y == -2) break;
-      }
-      if (x == 2) break;
-    }
-  }, -3);
-
-  assertThrowsEquals(() => {
-    for (let x of g1()) {
-      for (let y of g2()) {
-      }
-    }
-  }, -3);
-
-  assertThrowsEquals(() => {
-    for (let x of g1()) {
-      for (let y of g2()) {
-        if (y == -2) break;
-      }
-    }
-  }, 3);
-
-  assertDoesNotThrow(() => {
-    l: for (let x of g1()) {
-      for (let y of g2()) {
-        if (y == -2) break l;
-      }
-    }
-  });
-
-  assertThrowsEquals(() => {
-    for (let x of g1()) {
-      for (let y of g2()) {
-        throw 4;
-      }
-    }
-  }, 4);
-
-  assertThrowsEquals(() => {
-    for (let x of g1()) {
-      for (let y of g2()) {
-        if (y == -2) throw 4;
-      }
-    }
-  }, 4);
-
-  let log = [];
-  g1.prototype.return = () => { log.push(1); throw 5 };
-  g2.prototype.return = () => { log.push(2); throw -5 };
-
-  log = [];
-  assertThrowsEquals(() => {
-    for (let x of g1()) {
-      for (let y of g2()) {
-        if (y == -2) break;
-      }
-      if (x == 2) break;
-    }
-  }, -5);
-  assertEquals([2, 1], log);
-
-  log = [];
-  assertThrowsEquals(() => {
-    for (let x of g1()) {
-      for (let y of g2()) {
-      }
-    }
-  }, -3);
-  assertEquals([1], log);
-
-  log = [];
-  assertThrowsEquals(() => {
-    for (let x of g1()) {
-      for (let y of g2()) {
-        if (y == -2) break;
-      }
-    }
-  }, -5);
-  assertEquals([2, 1], log);
-
-  log = [];
-  assertThrowsEquals(() => {
-    l: for (let x of g1()) {
-      for (let y of g2()) {
-        if (y == -2) break l;
-      }
-    }
-  }, -5);
-  assertEquals([2, 1], log);
-
-  log = [];
-  assertThrowsEquals(() => {
-    for (let x of g1()) {
-      for (let y of g2()) {
-        throw 4;
-      }
-    }
-  }, 4);
-  assertEquals([2, 1], log);
-
-  log = [];
-  assertThrowsEquals(() => {
-    for (let x of g1()) {
-      for (let y of g2()) {
-        if (y == -2) throw 4;
-      }
-    }
-  }, 4);
-  assertEquals([2, 1], log);
-
-  log = [];
-  assertThrowsEquals(() => {
-    for (let x of g1()) {
-      try {
-        for (let y of g2()) {
-        }
-      } catch (_) {}
-    }
-  }, 3);
-  assertEquals([], log);
-
-  log = [];
-  assertThrowsEquals(() => {
-    for (let x of g1()) {
-      try {
-        for (let y of g2()) {
-        }
-      } catch (_) {}
-      if (x == 2) break;
-    }
-  }, 5);
-  assertEquals([1], log);
-}
-
-
-// yield*, argument's return method is "undefined".
-function TestYieldStarWithoutReturn(get_iterable) {
-  assertTrue(get_iterable().return == undefined);
-
-  function* g() { yield* get_iterable() }
-
-  {
-    let gen = g();
-    assertEquals({value: 1, done: false}, gen.next());
-    assertEquals({value: undefined, done: true}, gen.return());
-  }
-
-  assertEquals(42, (() => {
-    for (let x of g()) break;
-    return 42;
-  })());
-
-  assertEquals(42, (() => {
-    for (let x of g()) return 42;
-  })());
-
-  assertThrowsEquals(() => {
-    for (let x of g()) throw 42;
-  }, 42);
-}
-{
-  let get_iterable1 = () => [1, 2];
-  let get_iterable2 = function*() { yield 1; yield 2 };
-  get_iterable2.prototype.return = null;
-  TestYieldStarWithoutReturn(get_iterable1);
-  TestYieldStarWithoutReturn(get_iterable2);
-}
-
-
-// yield*, argument's return method is defined.
-{
-  let get_iterable = function*() { yield 1; yield 2 };
-  const obj = {};
-  get_iterable.prototype.return = (...args) => obj;
-
-  function* g() { yield* get_iterable() }
-
-  {
-    let gen = g();
-    assertEquals({value: 1, done: false}, gen.next());
-    assertSame(obj, gen.return());
-    assertSame(obj, gen.return());
-    assertSame(obj, gen.return());
-    assertEquals({value: 2, done: false}, gen.next());
-    assertSame(obj, gen.return());
-    assertSame(obj, gen.return());
-    assertSame(obj, gen.return());
-    assertEquals({value: undefined, done: true}, gen.next());
-    assertEquals({value: undefined, done: true}, gen.return());
-    assertEquals({value: undefined, done: true}, gen.return());
-  }
-
-  assertEquals(42, (() => {
-    for (let x of g()) break;
-    return 42;
-  })());
-
-  assertEquals(42, (() => {
-    for (let x of g()) return 42;
-  })());
-
-  assertThrowsEquals(() => {
-    for (let x of g()) throw 42;
-  }, 42);
-}
diff --git a/test/mjsunit/harmony/mirror-async-function-promise.js b/test/mjsunit/harmony/mirror-async-function-promise.js
new file mode 100644
index 0000000..966b0ce
--- /dev/null
+++ b/test/mjsunit/harmony/mirror-async-function-promise.js
@@ -0,0 +1,93 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --harmony-async-await --allow-natives-syntax
+// Test the mirror object for promises.
+
+var AsyncFunction = (async function() {}).constructor;
+
+function MirrorRefCache(json_refs) {
+  var tmp = eval('(' + json_refs + ')');
+  this.refs_ = [];
+  for (var i = 0; i < tmp.length; i++) {
+    this.refs_[tmp[i].handle] = tmp[i];
+  }
+}
+
+MirrorRefCache.prototype.lookup = function(handle) {
+  return this.refs_[handle];
+}
+
+function testPromiseMirror(promise, status, value) {
+  // Create mirror and JSON representation.
+  var mirror = debug.MakeMirror(promise);
+  var serializer = debug.MakeMirrorSerializer();
+  var json = JSON.stringify(serializer.serializeValue(mirror));
+  var refs = new MirrorRefCache(
+      JSON.stringify(serializer.serializeReferencedObjects()));
+
+  // Check the mirror hierachy.
+  assertTrue(mirror instanceof debug.Mirror);
+  assertTrue(mirror instanceof debug.ValueMirror);
+  assertTrue(mirror instanceof debug.ObjectMirror);
+  assertTrue(mirror instanceof debug.PromiseMirror);
+
+  // Check the mirror properties.
+  assertEquals(status, mirror.status());
+  assertTrue(mirror.isPromise());
+  assertEquals('promise', mirror.type());
+  assertFalse(mirror.isPrimitive());
+  assertEquals("Object", mirror.className());
+  assertEquals("#<Promise>", mirror.toText());
+  assertSame(promise, mirror.value());
+  assertTrue(mirror.promiseValue() instanceof debug.Mirror);
+  assertEquals(value, mirror.promiseValue().value());
+
+  // Parse JSON representation and check.
+  var fromJSON = eval('(' + json + ')');
+  assertEquals('promise', fromJSON.type);
+  assertEquals('Object', fromJSON.className);
+  assertEquals('function', refs.lookup(fromJSON.constructorFunction.ref).type);
+  assertEquals('Promise', refs.lookup(fromJSON.constructorFunction.ref).name);
+  assertEquals(status, fromJSON.status);
+  assertEquals(value, refs.lookup(fromJSON.promiseValue.ref).value);
+}
+
+// Test a number of different promises.
+var resolved = (async function() {})();
+var rejected = (async function() { throw undefined; })();
+var pending = (async function() { await 1; })();
+
+testPromiseMirror(resolved, "resolved", undefined);
+testPromiseMirror(rejected, "rejected", undefined);
+testPromiseMirror(pending, "pending", undefined);
+
+var resolvedv = (async function() { return "resolve"; })();
+var rejectedv = (async function() { return Promise.reject("reject"); })();
+var thrownv = (async function() { throw "throw"; })();
+
+testPromiseMirror(resolvedv, "resolved", 'resolve');
+testPromiseMirror(rejectedv, "rejected", 'reject');
+testPromiseMirror(thrownv, "rejected", 'throw');
+
+// Test internal properties of different promises.
+var m1 = debug.MakeMirror((async function() { return 1; })());
+var ip = m1.internalProperties();
+assertEquals(2, ip.length);
+assertEquals("[[PromiseStatus]]", ip[0].name());
+assertEquals("[[PromiseValue]]", ip[1].name());
+assertEquals("resolved", ip[0].value().value());
+assertEquals(1, ip[1].value().value());
+
+var m2 = debug.MakeMirror((async function() { throw 2; })());
+ip = m2.internalProperties();
+assertEquals("rejected", ip[0].value().value());
+assertEquals(2, ip[1].value().value());
+
+var m3 = debug.MakeMirror((async function() { await 1; })());
+ip = m3.internalProperties();
+assertEquals("pending", ip[0].value().value());
+assertEquals("undefined", typeof(ip[1].value().value()));
+
+%RunMicrotasks();
diff --git a/test/mjsunit/harmony/mirror-async-function.js b/test/mjsunit/harmony/mirror-async-function.js
new file mode 100644
index 0000000..b4ba831
--- /dev/null
+++ b/test/mjsunit/harmony/mirror-async-function.js
@@ -0,0 +1,76 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --harmony-async-await --allow-natives-syntax
+// Test the mirror object for functions.
+
+var AsyncFunction = (async function() {}).constructor;
+
+function MirrorRefCache(json_refs) {
+  var tmp = eval('(' + json_refs + ')');
+  this.refs_ = [];
+  for (var i = 0; i < tmp.length; i++) {
+    this.refs_[tmp[i].handle] = tmp[i];
+  }
+}
+
+MirrorRefCache.prototype.lookup = function(handle) {
+  return this.refs_[handle];
+}
+
+function testFunctionMirror(f) {
+  // Create mirror and JSON representation.
+  var mirror = debug.MakeMirror(f);
+  var serializer = debug.MakeMirrorSerializer();
+  var json = JSON.stringify(serializer.serializeValue(mirror));
+  var refs = new MirrorRefCache(
+      JSON.stringify(serializer.serializeReferencedObjects()));
+
+  // Check the mirror hierachy.
+  assertTrue(mirror instanceof debug.Mirror);
+  assertTrue(mirror instanceof debug.ValueMirror);
+  assertTrue(mirror instanceof debug.ObjectMirror);
+  assertTrue(mirror instanceof debug.FunctionMirror);
+
+  // Check the mirror properties.
+  assertTrue(mirror.isFunction());
+  assertEquals('function', mirror.type());
+  assertFalse(mirror.isPrimitive());
+  assertEquals("Function", mirror.className());
+  assertEquals(f.name, mirror.name());
+  assertTrue(mirror.resolved());
+  assertEquals(f.toString(), mirror.source());
+  assertTrue(mirror.constructorFunction() instanceof debug.ObjectMirror);
+  assertTrue(mirror.protoObject() instanceof debug.Mirror);
+  assertTrue(mirror.prototypeObject() instanceof debug.Mirror);
+
+  // Test text representation
+  assertEquals(f.toString(), mirror.toText());
+
+  // Parse JSON representation and check.
+  var fromJSON = eval('(' + json + ')');
+  assertEquals('function', fromJSON.type);
+  assertEquals('Function', fromJSON.className);
+  assertEquals('function', refs.lookup(fromJSON.constructorFunction.ref).type);
+  assertEquals('AsyncFunction',
+               refs.lookup(fromJSON.constructorFunction.ref).name);
+  assertTrue(fromJSON.resolved);
+  assertEquals(f.name, fromJSON.name);
+  assertEquals(f.toString(), fromJSON.source);
+
+  // Check the formatted text (regress 1142074).
+  assertEquals(f.toString(), fromJSON.text);
+}
+
+
+// Test a number of different functions.
+testFunctionMirror(async function(){});
+testFunctionMirror(AsyncFunction());
+testFunctionMirror(new AsyncFunction());
+testFunctionMirror(async() => {});
+testFunctionMirror(async function a(){return 1;});
+testFunctionMirror(({ async foo() {} }).foo);
+testFunctionMirror((async function(){}).bind({}), "Object");
+
+%RunMicrotasks();
diff --git a/test/mjsunit/harmony/promise-species.js b/test/mjsunit/harmony/promise-species.js
deleted file mode 100644
index 12244f2..0000000
--- a/test/mjsunit/harmony/promise-species.js
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-species --allow-natives-syntax
-
-// Test that Promises use @@species appropriately
-
-// Another constructor with no species will not be instantiated
-var test = new Promise(function(){});
-var bogoCount = 0;
-function bogusConstructor() { bogoCount++; }
-test.constructor = bogusConstructor;
-assertTrue(Promise.resolve(test) instanceof Promise);
-assertFalse(Promise.resolve(test) instanceof bogusConstructor);
-// Tests that chromium:575314 is fixed thoroughly
-Promise.resolve(test).catch(e => %AbortJS("Error " + e)).then(() => {
-  if (bogoCount != 0) %AbortJS("bogoCount was " + bogoCount + " should be 0");
-});
-
-// If there is a species, it will be instantiated
-// @@species will be read exactly once, and the constructor is called with a
-// function
-var count = 0;
-var params;
-class MyPromise extends Promise {
-  constructor(...args) {
-    super(...args);
-    params = args;
-  }
-  static get [Symbol.species]() {
-    count++
-    return this;
-  }
-}
-
-var myPromise = MyPromise.resolve().then();
-assertEquals(1, count);
-assertEquals(1, params.length);
-assertEquals('function', typeof(params[0]));
-assertTrue(myPromise instanceof MyPromise);
-assertTrue(myPromise instanceof Promise);
diff --git a/test/mjsunit/harmony/regexp-change-exec.js b/test/mjsunit/harmony/regexp-change-exec.js
index 4c9757e..ff84506 100644
--- a/test/mjsunit/harmony/regexp-change-exec.js
+++ b/test/mjsunit/harmony/regexp-change-exec.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Flags: --harmony-regexp-exec
-
 class MyError extends Error { }
 RegExp.prototype.exec = () => { throw new MyError() };
 assertThrows(() => "foo".match(/bar/), MyError);
diff --git a/test/mjsunit/harmony/regexp-named-captures.js b/test/mjsunit/harmony/regexp-named-captures.js
new file mode 100644
index 0000000..ced8e4b
--- /dev/null
+++ b/test/mjsunit/harmony/regexp-named-captures.js
@@ -0,0 +1,76 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-regexp-named-captures
+
+// Malformed named captures.
+assertThrows("/(?<>a)/u");  // Empty name.
+assertThrows("/(?<aa)/u");  // Unterminated name.
+assertThrows("/(?<42a>a)/u");  // Name starting with digits.
+assertThrows("/(?<:a>a)/u");  // Name starting with invalid char.
+assertThrows("/(?<a:>a)/u");  // Name containing with invalid char.
+assertThrows("/(?<a>a)(?<a>a)/u");  // Duplicate name.
+assertThrows("/(?<a>a)(?<b>b)(?<a>a)/u");  // Duplicate name.
+assertThrows("/\\k<a>/u");  // Invalid reference.
+assertThrows("/(?<a>a)\\k<ab>/u");  // Invalid reference.
+assertThrows("/(?<ab>a)\\k<a>/u");  // Invalid reference.
+assertThrows("/\\k<a>(?<ab>a)/u");  // Invalid reference.
+
+// Fallback behavior in non-unicode mode.
+assertThrows("/(?<>a)/");
+assertThrows("/(?<aa)/");
+assertThrows("/(?<42a>a)/");
+assertThrows("/(?<:a>a)/");
+assertThrows("/(?<a:>a)/");
+assertThrows("/(?<a>a)(?<a>a)/");
+assertThrows("/(?<a>a)(?<b>b)(?<a>a)/");
+assertThrows("/(?<a>a)\\k<ab>/");
+assertThrows("/(?<ab>a)\\k<a>/");
+
+assertEquals(["k<a>"], "xxxk<a>xxx".match(/\k<a>/));
+assertEquals(["k<a"], "xxxk<a>xxx".match(/\k<a/));
+
+// Basic named groups.
+assertEquals(["a", "a"], "bab".match(/(?<a>a)/u));
+assertEquals(["a", "a"], "bab".match(/(?<a42>a)/u));
+assertEquals(["a", "a"], "bab".match(/(?<_>a)/u));
+assertEquals(["a", "a"], "bab".match(/(?<$>a)/u));
+assertEquals(["bab", "a"], "bab".match(/.(?<$>a)./u));
+assertEquals(["bab", "a", "b"], "bab".match(/.(?<a>a)(.)/u));
+assertEquals(["bab", "a", "b"], "bab".match(/.(?<a>a)(?<b>.)/u));
+assertEquals(["bab", "ab"], "bab".match(/.(?<a>\w\w)/u));
+assertEquals(["bab", "bab"], "bab".match(/(?<a>\w\w\w)/u));
+assertEquals(["bab", "ba", "b"], "bab".match(/(?<a>\w\w)(?<b>\w)/u));
+
+assertEquals("bab".match(/(a)/u), "bab".match(/(?<a>a)/u));
+assertEquals("bab".match(/(a)/u), "bab".match(/(?<a42>a)/u));
+assertEquals("bab".match(/(a)/u), "bab".match(/(?<_>a)/u));
+assertEquals("bab".match(/(a)/u), "bab".match(/(?<$>a)/u));
+assertEquals("bab".match(/.(a)./u), "bab".match(/.(?<$>a)./u));
+assertEquals("bab".match(/.(a)(.)/u), "bab".match(/.(?<a>a)(.)/u));
+assertEquals("bab".match(/.(a)(.)/u), "bab".match(/.(?<a>a)(?<b>.)/u));
+assertEquals("bab".match(/.(\w\w)/u), "bab".match(/.(?<a>\w\w)/u));
+assertEquals("bab".match(/(\w\w\w)/u), "bab".match(/(?<a>\w\w\w)/u));
+assertEquals("bab".match(/(\w\w)(\w)/u), "bab".match(/(?<a>\w\w)(?<b>\w)/u));
+
+assertEquals(["bab", "b"], "bab".match(/(?<b>b).\1/u));
+assertEquals(["baba", "b", "a"], "baba".match(/(.)(?<a>a)\1\2/u));
+assertEquals(["baba", "b", "a", "b", "a"],
+    "baba".match(/(.)(?<a>a)(?<b>\1)(\2)/u));
+assertEquals(["<a", "<"], "<a".match(/(?<lt><)a/u));
+assertEquals([">a", ">"], ">a".match(/(?<gt>>)a/u));
+
+// Named references.
+assertEquals(["bab", "b"], "bab".match(/(?<b>.).\k<b>/u));
+assertNull("baa".match(/(?<b>.).\k<b>/u));
+
+// Nested groups.
+assertEquals(["bab", "bab", "ab", "b"], "bab".match(/(?<a>.(?<b>.(?<c>.)))/u));
+
+// Reference inside group.
+assertEquals(["bab", "b"], "bab".match(/(?<a>\k<a>\w)../u));
+
+// Reference before group.
+assertEquals(["bab", "b"], "bab".match(/\k<a>(?<a>b)\w\k<a>/u));
+assertEquals(["bab", "b", "a"], "bab".match(/(?<b>b)\k<a>(?<a>a)\k<b>/u));
diff --git a/test/mjsunit/harmony/regexp-no-change-exec.js b/test/mjsunit/harmony/regexp-no-change-exec.js
deleted file mode 100644
index 30b5050..0000000
--- a/test/mjsunit/harmony/regexp-no-change-exec.js
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --no-harmony-regexp-exec
-
-class MyError extends Error { }
-RegExp.prototype.exec = () => { throw new MyError() };
-assertEquals(null, "foo".match(/bar/));
diff --git a/test/mjsunit/harmony/regexp-property-binary.js b/test/mjsunit/harmony/regexp-property-binary.js
index d0894b7..c0b4426 100644
--- a/test/mjsunit/harmony/regexp-property-binary.js
+++ b/test/mjsunit/harmony/regexp-property-binary.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Flags: --harmony-regexp-property --harmony-unicode-regexps
+// Flags: --harmony-regexp-property
 
 function t(re, s) { assertTrue(re.test(s)); }
 function f(re, s) { assertFalse(re.test(s)); }
diff --git a/test/mjsunit/harmony/regexp-property-blocks.js b/test/mjsunit/harmony/regexp-property-blocks.js
index f41c06e..de3fd1e 100644
--- a/test/mjsunit/harmony/regexp-property-blocks.js
+++ b/test/mjsunit/harmony/regexp-property-blocks.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Flags: --harmony-regexp-property --harmony-unicode-regexps
+// Flags: --harmony-regexp-property
 
 function t(re, s) { assertTrue(re.test(s)); }
 function f(re, s) { assertFalse(re.test(s)); }
diff --git a/test/mjsunit/harmony/regexp-property-char-class.js b/test/mjsunit/harmony/regexp-property-char-class.js
index 6162012..c70e826 100644
--- a/test/mjsunit/harmony/regexp-property-char-class.js
+++ b/test/mjsunit/harmony/regexp-property-char-class.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Flags: --harmony-unicode-regexps --harmony-regexp-property
+// Flags: --harmony-regexp-property
 
 assertThrows("/[\\p]/u");
 assertThrows("/[\\p{garbage}]/u");
diff --git a/test/mjsunit/harmony/regexp-property-disabled.js b/test/mjsunit/harmony/regexp-property-disabled.js
index 7a3158c..f471ef4 100644
--- a/test/mjsunit/harmony/regexp-property-disabled.js
+++ b/test/mjsunit/harmony/regexp-property-disabled.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Flags: --harmony-unicode-regexps --no-harmony-regexp-property
+// Flags: --no-harmony-regexp-property
 
 function test(source, message) {
   try {
diff --git a/test/mjsunit/harmony/regexp-property-enumerated.js b/test/mjsunit/harmony/regexp-property-enumerated.js
index e4a81a4..dba8397 100644
--- a/test/mjsunit/harmony/regexp-property-enumerated.js
+++ b/test/mjsunit/harmony/regexp-property-enumerated.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Flags: --harmony-regexp-property --harmony-unicode-regexps
+// Flags: --harmony-regexp-property
 
 function t(re, s) { assertTrue(re.test(s)); }
 function f(re, s) { assertFalse(re.test(s)); }
diff --git a/test/mjsunit/harmony/regexp-property-exact-match.js b/test/mjsunit/harmony/regexp-property-exact-match.js
index fe233f2..0d1f704 100644
--- a/test/mjsunit/harmony/regexp-property-exact-match.js
+++ b/test/mjsunit/harmony/regexp-property-exact-match.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Flags: --harmony-regexp-property --harmony-unicode-regexps
+// Flags: --harmony-regexp-property
 
 assertThrows("/\\p{In CJK}/u");
 assertThrows("/\\p{InCJKUnifiedIdeographs}/u");
@@ -15,7 +15,7 @@
 assertThrows("/\\p{InCyrillicSupplementary}/u");
 assertThrows("/\\p{InCyrillic_supplementary}/u");
 
-assertDoesNotThrow("/\\pC/u");
+assertDoesNotThrow("/\\p{C}/u");
 assertDoesNotThrow("/\\p{Other}/u");
 assertDoesNotThrow("/\\p{Cc}/u");
 assertDoesNotThrow("/\\p{Control}/u");
diff --git a/test/mjsunit/harmony/regexp-property-general-category.js b/test/mjsunit/harmony/regexp-property-general-category.js
index e2015ad..e4fb8b5 100644
--- a/test/mjsunit/harmony/regexp-property-general-category.js
+++ b/test/mjsunit/harmony/regexp-property-general-category.js
@@ -2,16 +2,20 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Flags: --harmony-regexp-property --harmony-unicode-regexps
+// Flags: --harmony-regexp-property
 
 assertThrows("/\\p/u");
 assertThrows("/\\p{garbage}/u");
 assertThrows("/\\p{}/u");
 assertThrows("/\\p{/u");
 assertThrows("/\\p}/u");
-assertThrows("/\p{Math}/u");
-assertThrows("/\p{Bidi_M}/u");
-assertThrows("/\p{Hex}/u");
+assertThrows("/\\pL/u");
+assertThrows("/\\P/u");
+assertThrows("/\\P{garbage}/u");
+assertThrows("/\\P{}/u");
+assertThrows("/\\P{/u");
+assertThrows("/\\P}/u");
+assertThrows("/\\PL/u");
 
 assertTrue(/\p{Ll}/u.test("a"));
 assertFalse(/\P{Ll}/u.test("a"));
@@ -26,10 +30,10 @@
 assertTrue(/\p{Ll}/iu.test("\u{118D4}"));
 assertTrue(/\p{Ll}/iu.test("A"));
 assertTrue(/\p{Ll}/iu.test("\u{118B4}"));
-assertFalse(/\P{Ll}/iu.test("a"));
-assertFalse(/\P{Ll}/iu.test("\u{118D4}"));
-assertFalse(/\P{Ll}/iu.test("A"));
-assertFalse(/\P{Ll}/iu.test("\u{118B4}"));
+assertTrue(/\P{Ll}/iu.test("a"));
+assertTrue(/\P{Ll}/iu.test("\u{118D4}"));
+assertTrue(/\P{Ll}/iu.test("A"));
+assertTrue(/\P{Ll}/iu.test("\u{118B4}"));
 
 assertTrue(/\p{Lu}/u.test("A"));
 assertFalse(/\P{Lu}/u.test("A"));
@@ -44,22 +48,16 @@
 assertTrue(/\p{Lu}/iu.test("\u{118D4}"));
 assertTrue(/\p{Lu}/iu.test("A"));
 assertTrue(/\p{Lu}/iu.test("\u{118B4}"));
-assertFalse(/\P{Lu}/iu.test("a"));
-assertFalse(/\P{Lu}/iu.test("\u{118D4}"));
-assertFalse(/\P{Lu}/iu.test("A"));
-assertFalse(/\P{Lu}/iu.test("\u{118B4}"));
+assertTrue(/\P{Lu}/iu.test("a"));
+assertTrue(/\P{Lu}/iu.test("\u{118D4}"));
+assertTrue(/\P{Lu}/iu.test("A"));
+assertTrue(/\P{Lu}/iu.test("\u{118B4}"));
 
 assertTrue(/\p{Sm}/u.test("+"));
 assertFalse(/\P{Sm}/u.test("+"));
 assertTrue(/\p{Sm}/u.test("\u{1D6C1}"));
 assertFalse(/\P{Sm}/u.test("\u{1D6C1}"));
 
-assertTrue(/\pL/u.test("a"));
-assertFalse(/\PL/u.test("a"));
-assertFalse(/\pL/u.test("1"));
-assertTrue(/\PL/u.test("1"));
-assertTrue(/\pL/u.test("\u1FAB"));
-assertFalse(/\PL/u.test("\u1FAB"));
 assertFalse(/\p{L}/u.test("\uA6EE"));
 assertTrue(/\P{L}/u.test("\uA6EE"));
 
diff --git a/test/mjsunit/harmony/regexp-property-lu-ui.js b/test/mjsunit/harmony/regexp-property-lu-ui.js
new file mode 100644
index 0000000..115e064
--- /dev/null
+++ b/test/mjsunit/harmony/regexp-property-lu-ui.js
@@ -0,0 +1,13 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-regexp-property
+
+const regexp = /\P{Lu}/ui;
+const regexpu = /[\0-@\[-\xBF\xD7\xDF-\xFF\u0101\u0103\u0105\u0107\u0109\u010B\u010D\u010F\u0111\u0113\u0115\u0117\u0119\u011B\u011D\u011F\u0121\u0123\u0125\u0127\u0129\u012B\u012D\u012F\u0131\u0133\u0135\u0137\u0138\u013A\u013C\u013E\u0140\u0142\u0144\u0146\u0148\u0149\u014B\u014D\u014F\u0151\u0153\u0155\u0157\u0159\u015B\u015D\u015F\u0161\u0163\u0165\u0167\u0169\u016B\u016D\u016F\u0171\u0173\u0175\u0177\u017A\u017C\u017E-\u0180\u0183\u0185\u0188\u018C\u018D\u0192\u0195\u0199-\u019B\u019E\u01A1\u01A3\u01A5\u01A8\u01AA\u01AB\u01AD\u01B0\u01B4\u01B6\u01B9-\u01BB\u01BD-\u01C3\u01C5\u01C6\u01C8\u01C9\u01CB\u01CC\u01CE\u01D0\u01D2\u01D4\u01D6\u01D8\u01DA\u01DC\u01DD\u01DF\u01E1\u01E3\u01E5\u01E7\u01E9\u01EB\u01ED\u01EF\u01F0\u01F2\u01F3\u01F5\u01F9\u01FB\u01FD\u01FF\u0201\u0203\u0205\u0207\u0209\u020B\u020D\u020F\u0211\u0213\u0215\u0217\u0219\u021B\u021D\u021F\u0221\u0223\u0225\u0227\u0229\u022B\u022D\u022F\u0231\u0233-\u0239\u023C\u023F\u0240\u0242\u0247\u0249\u024B\u024D\u024F-\u036F\u0371\u0373-\u0375\u0377-\u037E\u0380-\u0385\u0387\u038B\u038D\u0390\u03A2\u03AC-\u03CE\u03D0\u03D1\u03D5-\u03D7\u03D9\u03DB\u03DD\u03DF\u03E1\u03E3\u03E5\u03E7\u03E9\u03EB\u03ED\u03EF-\u03F3\u03F5\u03F6\u03F8\u03FB\u03FC\u0430-\u045F\u0461\u0463\u0465\u0467\u0469\u046B\u046D\u046F\u0471\u0473\u0475\u0477\u0479\u047B\u047D\u047F\u0481-\u0489\u048B\u048D\u048F\u0491\u0493\u0495\u0497\u0499\u049B\u049D\u049F\u04A1\u04A3\u04A5\u04A7\u04A9\u04AB\u04AD\u04AF\u04B1\u04B3\u04B5\u04B7\u04B9\u04BB\u04BD\u04BF\u04C2\u04C4\u04C6\u04C8\u04CA\u04CC\u04CE\u04CF\u04D1\u04D3\u04D5\u04D7\u04D9\u04DB\u04DD\u04DF\u04E1\u04E3\u04E5\u04E7\u04E9\u04EB\u04ED\u04EF\u04F1\u04F3\u04F5\u04F7\u04F9\u04FB\u04FD\u04FF\u0501\u0503\u0505\u0507\u0509\u050B\u050D\u050F\u0511\u0513\u0515\u0517\u0519\u051B\u051D\u051F\u0521\u0523\u0525\u0527\u0529\u052B\u052D\u052F\u0530\u0557-\u109F\u10C6\u10C8-\u10CC\u10CE-\u139F\u13F6-\u1DFF\u1E01\u1E03\u1E05\u1E07\u1E09\u1E0B\u1E0D\u1E0F\u1E11\u1E13\u1E15\u1E17\u1E19\u1E1B\u1E1D\u1E1F\u1E21\u1E23\u1E25\u1E27\u1E29\u1E2B\u1E2D\u1E2F\u1E31\u1E33\u1E35\u1E37\u1E39\u1E3B\u1E3D\u1E3F\u1E41\u1E43\u1E45\u1E47\u1E49\u1E4B\u1E4D\u1E4F\u1E51\u1E53\u1E55\u1E57\u1E59\u1E5B\u1E5D\u1E5F\u1E61\u1E63\u1E65\u1E67\u1E69\u1E6B\u1E6D\u1E6F\u1E71\u1E73\u1E75\u1E77\u1E79\u1E7B\u1E7D\u1E7F\u1E81\u1E83\u1E85\u1E87\u1E89\u1E8B\u1E8D\u1E8F\u1E91\u1E93\u1E95-\u1E9D\u1E9F\u1EA1\u1EA3\u1EA5\u1EA7\u1EA9\u1EAB\u1EAD\u1EAF\u1EB1\u1EB3\u1EB5\u1EB7\u1EB9\u1EBB\u1EBD\u1EBF\u1EC1\u1EC3\u1EC5\u1EC7\u1EC9\u1ECB\u1ECD\u1ECF\u1ED1\u1ED3\u1ED5\u1ED7\u1ED9\u1EDB\u1EDD\u1EDF\u1EE1\u1EE3\u1EE5\u1EE7\u1EE9\u1EEB\u1EED\u1EEF\u1EF1\u1EF3\u1EF5\u1EF7\u1EF9\u1EFB\u1EFD\u1EFF-\u1F07\u1F10-\u1F17\u1F1E-\u1F27\u1F30-\u1F37\u1F40-\u1F47\u1F4E-\u1F58\u1F5A\u1F5C\u1F5E\u1F60-\u1F67\u1F70-\u1FB7\u1FBC-\u1FC7\u1FCC-\u1FD7\u1FDC-\u1FE7\u1FED-\u1FF7\u1FFC-\u2101\u2103-\u2106\u2108-\u210A\u210E\u210F\u2113\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u212F\u2134-\u213D\u2140-\u2144\u2146-\u2182\u2184-\u2BFF\u2C2F-\u2C5F\u2C61\u2C65\u2C66\u2C68\u2C6A\u2C6C\u2C71\u2C73\u2C74\u2C76-\u2C7D\u2C81\u2C83\u2C85\u2C87\u2C89\u2C8B\u2C8D\u2C8F\u2C91\u2C93\u2C95\u2C97\u2C99\u2C9B\u2C9D\u2C9F\u2CA1\u2CA3\u2CA5\u2CA7\u2CA9\u2CAB\u2CAD\u2CAF\u2CB1\u2CB3\u2CB5\u2CB7\u2CB9\u2CBB\u2CBD\u2CBF\u2CC1\u2CC3\u2CC5\u2CC7\u2CC9\u2CCB\u2CCD\u2CCF\u2CD1\u2CD3\u2CD5\u2CD7\u2CD9\u2CDB\u2CDD\u2CDF\u2CE1\u2CE3-\u2CEA\u2CEC\u2CEE-\u2CF1\u2CF3-\uA63F\uA641\uA643\uA645\uA647\uA649\uA64B\uA64D\uA64F\uA651\uA653\uA655\uA657\uA659\uA65B\uA65D\uA65F\uA661\uA663\uA665\uA667\uA669\uA66B\uA66D-\uA67F\uA681\uA683\uA685\uA687\uA689\uA68B\uA68D\uA68F\uA691\uA693\uA695\uA697\uA699\uA69B-\uA721\uA723\uA725\uA727\uA729\uA72B\uA72D\uA72F-\uA731\uA733\uA735\uA737\uA739\uA73B\uA73D\uA73F\uA741\uA743\uA745\uA747\uA749\uA74B\uA74D\uA74F\uA751\uA753\uA755\uA757\uA759\uA75B\uA75D\uA75F\uA761\uA763\uA765\uA767\uA769\uA76B\uA76D\uA76F-\uA778\uA77A\uA77C\uA77F\uA781\uA783\uA785\uA787-\uA78A\uA78C\uA78E\uA78F\uA791\uA793-\uA795\uA797\uA799\uA79B\uA79D\uA79F\uA7A1\uA7A3\uA7A5\uA7A7\uA7A9\uA7AE\uA7AF\uA7B5\uA7B7-\uFF20\uFF3B-\u{103FF}\u{10428}-\u{10C7F}\u{10CB3}-\u{1189F}\u{118C0}-\u{1D3FF}\u{1D41A}-\u{1D433}\u{1D44E}-\u{1D467}\u{1D482}-\u{1D49B}\u{1D49D}\u{1D4A0}\u{1D4A1}\u{1D4A3}\u{1D4A4}\u{1D4A7}\u{1D4A8}\u{1D4AD}\u{1D4B6}-\u{1D4CF}\u{1D4EA}-\u{1D503}\u{1D506}\u{1D50B}\u{1D50C}\u{1D515}\u{1D51D}-\u{1D537}\u{1D53A}\u{1D53F}\u{1D545}\u{1D547}-\u{1D549}\u{1D551}-\u{1D56B}\u{1D586}-\u{1D59F}\u{1D5BA}-\u{1D5D3}\u{1D5EE}-\u{1D607}\u{1D622}-\u{1D63B}\u{1D656}-\u{1D66F}\u{1D68A}-\u{1D6A7}\u{1D6C1}-\u{1D6E1}\u{1D6FB}-\u{1D71B}\u{1D735}-\u{1D755}\u{1D76F}-\u{1D78F}\u{1D7A9}-\u{1D7C9}\u{1D7CB}-\u{10FFFF}]/ui;
+
+for (let codePoint = 0; codePoint <= 0x10FFFF; codePoint++) {
+  const string = String.fromCodePoint(codePoint);
+  assertEquals(regexp.test(string), regexpu.test(string));
+}
diff --git a/test/mjsunit/harmony/regexp-property-scripts.js b/test/mjsunit/harmony/regexp-property-scripts.js
index ec2b11d..565a59a 100644
--- a/test/mjsunit/harmony/regexp-property-scripts.js
+++ b/test/mjsunit/harmony/regexp-property-scripts.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Flags: --harmony-regexp-property --harmony-unicode-regexps
+// Flags: --harmony-regexp-property
 
 function t(re, s) { assertTrue(re.test(s)); }
 function f(re, s) { assertFalse(re.test(s)); }
diff --git a/test/mjsunit/harmony/regexp-property-special.js b/test/mjsunit/harmony/regexp-property-special.js
new file mode 100644
index 0000000..204b77f
--- /dev/null
+++ b/test/mjsunit/harmony/regexp-property-special.js
@@ -0,0 +1,51 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-regexp-property
+
+function t(re, s) { assertTrue(re.test(s)); }
+function f(re, s) { assertFalse(re.test(s)); }
+
+t(/\p{ASCII}+/u, "abc123");
+f(/\p{ASCII}+/u, "ⓐⓑⓒ①②③");
+f(/\p{ASCII}+/u, "🄰🄱🄲①②③");
+f(/\P{ASCII}+/u, "abcd123");
+t(/\P{ASCII}+/u, "ⓐⓑⓒ①②③");
+t(/\P{ASCII}+/u, "🄰🄱🄲①②③");
+
+f(/[^\p{ASCII}]+/u, "abc123");
+f(/[\p{ASCII}]+/u, "ⓐⓑⓒ①②③");
+f(/[\p{ASCII}]+/u, "🄰🄱🄲①②③");
+t(/[^\P{ASCII}]+/u, "abcd123");
+t(/[\P{ASCII}]+/u, "ⓐⓑⓒ①②③");
+f(/[^\P{ASCII}]+/u, "🄰🄱🄲①②③");
+
+t(/\p{Any}+/u, "🄰🄱🄲①②③");
+
+assertEquals(["\ud800"], /\p{Any}/u.exec("\ud800\ud801"));
+assertEquals(["\udc00"], /\p{Any}/u.exec("\udc00\udc01"));
+assertEquals(["\ud800\udc01"], /\p{Any}/u.exec("\ud800\udc01"));
+assertEquals(["\udc01"], /\p{Any}/u.exec("\udc01"));
+
+f(/\P{Any}+/u, "123");
+f(/[\P{Any}]+/u, "123");
+t(/[\P{Any}\d]+/u, "123");
+t(/[^\P{Any}]+/u, "123");
+
+t(/\p{Assigned}+/u, "123");
+t(/\p{Assigned}+/u, "🄰🄱🄲");
+f(/\p{Assigned}+/u, "\ufdd0");
+f(/\p{Assigned}+/u, "\u{fffff}");
+
+f(/\P{Assigned}+/u, "123");
+f(/\P{Assigned}+/u, "🄰🄱🄲");
+t(/\P{Assigned}+/u, "\ufdd0");
+t(/\P{Assigned}+/u, "\u{fffff}");
+f(/\P{Assigned}/u, "");
+
+t(/[^\P{Assigned}]+/u, "123");
+f(/[\P{Assigned}]+/u, "🄰🄱🄲");
+f(/[^\P{Assigned}]+/u, "\ufdd0");
+t(/[\P{Assigned}]+/u, "\u{fffff}");
+f(/[\P{Assigned}]/u, "");
diff --git a/test/mjsunit/harmony/regress/regress-618603.js b/test/mjsunit/harmony/regress/regress-618603.js
new file mode 100644
index 0000000..7b23ef4
--- /dev/null
+++ b/test/mjsunit/harmony/regress/regress-618603.js
@@ -0,0 +1,14 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-async-await --ignition-generators
+
+try {
+} catch(e) {; }
+function __f_7(expected, run) {
+  var __v_10 = run();
+};
+__f_7("[1,2,3]", () => (function() {
+      return (async () => {[...await arguments] })();
+      })());
diff --git a/test/mjsunit/harmony/regress/regress-crbug-621111.js b/test/mjsunit/harmony/regress/regress-crbug-621111.js
new file mode 100644
index 0000000..58a0d5c
--- /dev/null
+++ b/test/mjsunit/harmony/regress/regress-crbug-621111.js
@@ -0,0 +1,6 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(y = 1[1, [...[]]]) => 1;   // will core dump, if not fixed
+(y = 1[1, [...[]]]) => {};  // will core dump, if not fixed
diff --git a/test/mjsunit/harmony/regress/regress-crbug-621496.js b/test/mjsunit/harmony/regress/regress-crbug-621496.js
new file mode 100644
index 0000000..4db7a95
--- /dev/null
+++ b/test/mjsunit/harmony/regress/regress-crbug-621496.js
@@ -0,0 +1,7 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function testIllegalSpreadAsSingleArrowParameter() {
+  assertThrows("(...[42]) => 42)", SyntaxError)  // will core dump, if not fixed
+})();
diff --git a/test/mjsunit/harmony/simd.js b/test/mjsunit/harmony/simd.js
index 1868050..a3d4615 100644
--- a/test/mjsunit/harmony/simd.js
+++ b/test/mjsunit/harmony/simd.js
@@ -622,7 +622,9 @@
 
 function TestStringify(expected, input) {
   assertEquals(expected, JSON.stringify(input));
-  assertEquals(expected, JSON.stringify(input, null, 0));
+  assertEquals(expected, JSON.stringify(input, (key, value) => value));
+  assertEquals(JSON.stringify(input, null, "="),
+               JSON.stringify(input, (key, value) => value, "="));
 }
 
 TestStringify(undefined, SIMD.Float32x4(1, 2, 3, 4));
diff --git a/test/mjsunit/harmony/sloppy-legacy-duplicate-generators.js b/test/mjsunit/harmony/sloppy-legacy-duplicate-generators.js
new file mode 100644
index 0000000..1fde475
--- /dev/null
+++ b/test/mjsunit/harmony/sloppy-legacy-duplicate-generators.js
@@ -0,0 +1,60 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --no-harmony-restrictive-generators
+
+// In legacy mode, generators get sloppy-mode block-scoped function hoisting
+
+// Hoisting to the global scope
+
+{
+  function* foo() {}
+  assertEquals('function', typeof foo);
+}
+//assertEquals('function', typeof foo);
+
+// Hoisting within a function scope
+(function() {
+  { function* bar() {} }
+  assertEquals('function', typeof bar);
+})();
+
+// Lexical shadowing allowed; hoisting happens
+(function() {
+  function* x() { yield 1; }
+  { function* x() { yield 2 } }
+  assertEquals(2, x().next().value);
+})();
+
+// Duplicates allowed
+(function() {
+  function* y() { yield 1; }
+  function* y() { yield 2 }
+  assertEquals(2, y().next().value);
+})();
+
+// Functions and generators may duplicate each other
+(function() {
+  function* z() { yield 1; }
+  function z() { return 2 }
+  assertEquals(2, z());
+
+  function a() { return 1; }
+  function* a() { yield 2 }
+  assertEquals(2, a().next().value);
+})();
+
+// In strict mode, none of this happens
+
+(function() {
+  'use strict';
+
+  { function* bar() {} }
+  assertEquals('undefined', typeof bar);
+
+  // Lexical shadowing allowed; hoisting happens
+  function* x() { yield 1; }
+  { function* x() { yield 2 } }
+  assertEquals(1, x().next().value);
+})();
diff --git a/test/mjsunit/harmony/sloppy-no-duplicate-async.js b/test/mjsunit/harmony/sloppy-no-duplicate-async.js
new file mode 100644
index 0000000..97411c0
--- /dev/null
+++ b/test/mjsunit/harmony/sloppy-no-duplicate-async.js
@@ -0,0 +1,30 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-async-await
+
+// Async functions don't get sloppy-mode block-scoped function hoisting
+
+// No hoisting to the global scope
+
+{
+  async function foo() {}
+  assertEquals('function', typeof foo);
+}
+assertEquals('undefined', typeof foo);
+
+// No hoisting within a function scope
+(function() {
+  { async function bar() {} }
+  assertEquals('undefined', typeof bar);
+})();
+
+// Lexical shadowing allowed, no hoisting
+(function() {
+  var y;
+  async function x() { y = 1; }
+  { async function x() { y = 2; } }
+  x();
+  assertEquals(1, y);
+})();
diff --git a/test/mjsunit/harmony/sloppy-no-duplicate-generators.js b/test/mjsunit/harmony/sloppy-no-duplicate-generators.js
new file mode 100644
index 0000000..de2e461
--- /dev/null
+++ b/test/mjsunit/harmony/sloppy-no-duplicate-generators.js
@@ -0,0 +1,28 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-restrictive-generators
+
+// Generators don't get sloppy-mode block-scoped function hoisting
+
+// No hoisting to the global scope
+
+{
+  function* foo() {}
+  assertEquals('function', typeof foo);
+}
+assertEquals('undefined', typeof foo);
+
+// No hoisting within a function scope
+(function() {
+  { function* bar() {} }
+  assertEquals('undefined', typeof bar);
+})();
+
+// Lexical shadowing allowed, no hoisting
+(function() {
+  function* x() { yield 1; }
+  { function* x() { yield 2 } }
+  assertEquals(1, x().next().value);
+})();
diff --git a/test/mjsunit/harmony/species.js b/test/mjsunit/harmony/species.js
deleted file mode 100644
index da1df43..0000000
--- a/test/mjsunit/harmony/species.js
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-species
-
-// Test the ES2015 @@species feature
-
-'use strict';
-
-let TypedArray = Uint8Array.__proto__;
-
-// The @@species property exists on the right objects and has the right values
-
-let classesWithSpecies = [RegExp, Array, TypedArray, ArrayBuffer, Map, Set, Promise];
-let classesWithoutSpecies = [Object, Function, String, Number, Symbol, WeakMap, WeakSet];
-
-for (let constructor of classesWithSpecies) {
-  assertEquals(constructor, constructor[Symbol.species]);
-  assertThrows(function() { constructor[Symbol.species] = undefined }, TypeError);
-  let descriptor = Object.getOwnPropertyDescriptor(constructor, Symbol.species);
-  assertTrue(descriptor.configurable);
-  assertFalse(descriptor.enumerable);
-  assertEquals(undefined, descriptor.writable);
-  assertEquals(undefined, descriptor.set);
-  assertEquals('function', typeof descriptor.get);
-}
-
-// @@species is defined with distinct getters
-assertEquals(classesWithSpecies.length,
-             new Set(classesWithSpecies.map(constructor =>
-                                            Object.getOwnPropertyDescriptor(
-                                              constructor, Symbol.species).get)
-                ).size);
-
-for (let constructor of classesWithoutSpecies)
-  assertEquals(undefined, constructor[Symbol.species]);
diff --git a/test/mjsunit/harmony/string-match.js b/test/mjsunit/harmony/string-match.js
deleted file mode 100644
index 25a3ca2..0000000
--- a/test/mjsunit/harmony/string-match.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-regexp-subclass
-
-var pattern = {};
-pattern[Symbol.match] = function(string) {
-  return string.length;
-};
-// Check object coercible fails.
-assertThrows(() => String.prototype.match.call(null, pattern),
-             TypeError);
-// Override is called.
-assertEquals(5, "abcde".match(pattern));
-// Non-callable override.
-pattern[Symbol.match] = "dumdidum";
-assertThrows(() => "abcde".match(pattern), TypeError);
-
-assertEquals("[Symbol.match]", RegExp.prototype[Symbol.match].name);
diff --git a/test/mjsunit/harmony/string-replace.js b/test/mjsunit/harmony/string-replace.js
deleted file mode 100644
index 208c483..0000000
--- a/test/mjsunit/harmony/string-replace.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-regexp-subclass
-
-var pattern = {
-  [Symbol.replace]: (string, newValue) => string + newValue
-};
-// Check object coercible fails.
-assertThrows(() => String.prototype.replace.call(null, pattern, "x"),
-             TypeError);
-// Override is called.
-assertEquals("abcdex", "abcde".replace(pattern, "x"));
-// Non-callable override.
-pattern[Symbol.replace] = "dumdidum";
-assertThrows(() => "abcde".replace(pattern, "x"), TypeError);
-
-assertEquals("[Symbol.replace]", RegExp.prototype[Symbol.replace].name);
diff --git a/test/mjsunit/harmony/string-split.js b/test/mjsunit/harmony/string-split.js
deleted file mode 100644
index 1240d84..0000000
--- a/test/mjsunit/harmony/string-split.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-regexp-subclass
-
-var pattern = {};
-var limit = { value: 3 };
-pattern[Symbol.split] = function(string, limit) {
-  return string.length * limit.value;
-};
-// Check object coercible fails.
-assertThrows(() => String.prototype.split.call(null, pattern, limit),
-             TypeError);
-// Override is called.
-assertEquals(15, "abcde".split(pattern, limit));
-// Non-callable override.
-pattern[Symbol.split] = "dumdidum";
-assertThrows(() => "abcde".split(pattern, limit), TypeError);
-
-assertEquals("[Symbol.split]", RegExp.prototype[Symbol.split].name);
diff --git a/test/mjsunit/harmony/typedarray-species.js b/test/mjsunit/harmony/typedarray-species.js
deleted file mode 100644
index 35a9ea1..0000000
--- a/test/mjsunit/harmony/typedarray-species.js
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-species
-
-// Subclasses of %TypedArray% construct themselves under map, etc
-
-var typedArrayConstructors = [
-  Uint8Array,
-  Int8Array,
-  Uint16Array,
-  Int16Array,
-  Uint32Array,
-  Int32Array,
-  Uint8ClampedArray,
-  Float32Array,
-  Float64Array
-];
-
-for (let constructor of typedArrayConstructors) {
-  class MyTypedArray extends constructor { }
-  assertEquals(MyTypedArray, new MyTypedArray().map(()=>0).constructor);
-  assertEquals(MyTypedArray, new MyTypedArray().filter(()=>{}).constructor);
-  assertEquals(MyTypedArray, new MyTypedArray().slice().constructor);
-}
-
-// Subclasses can override @@species to return the another class
-
-for (let constructor of typedArrayConstructors) {
-  class MyTypedArray extends constructor { }
-  class MyOtherTypedArray extends constructor {
-    static get [Symbol.species]() { return MyTypedArray; }
-  }
-  assertEquals(MyTypedArray, new MyOtherTypedArray().map(()=>0).constructor);
-  assertEquals(MyTypedArray, new MyOtherTypedArray().filter(()=>{}).constructor);
-  assertEquals(MyTypedArray, new MyOtherTypedArray().slice().constructor);
-}
-
-// TypedArray too-short and non-TypedArray error checking
-
-for (let constructor of typedArrayConstructors) {
-  class MyShortTypedArray extends constructor {
-    constructor(length) { super(length - 1); }
-  }
-  assertThrows(() => new MyShortTypedArray(5).map(()=>0), TypeError);
-  assertThrows(() => new MyShortTypedArray(5).filter(()=>true), TypeError);
-  assertThrows(() => new MyShortTypedArray(5).slice(), TypeError);
-
-  class MyNonTypedArray extends constructor {
-    static get [Symbol.species]() { return Array; }
-  }
-  assertThrows(() => new MyNonTypedArray().map(()=>0), TypeError);
-  assertThrows(() => new MyNonTypedArray().filter(()=>{}), TypeError);
-  assertThrows(() => new MyNonTypedArray().slice(), TypeError);
-}
-
-// Defaults when constructor or @@species is missing or non-constructor
-
-for (let constructor of typedArrayConstructors) {
-  class MyDefaultTypedArray extends constructor {
-    static get [Symbol.species]() { return undefined; }
-  }
-  assertEquals(constructor, new MyDefaultTypedArray().map(()=>0).constructor);
-
-  class MyOtherDefaultTypedArray extends constructor { }
-  assertEquals(MyOtherDefaultTypedArray, new MyOtherDefaultTypedArray().map(()=>0).constructor);
-  MyOtherDefaultTypedArray.prototype.constructor = undefined;
-  assertEquals(constructor, new MyOtherDefaultTypedArray().map(()=>0).constructor);
-}
-
-// Exceptions propagated when getting constructor @@species throws
-
-class SpeciesError extends Error { }
-class ConstructorError extends Error { }
-
-for (let constructor of typedArrayConstructors) {
-  class MyThrowingArray extends constructor {
-    static get [Symbol.species]() { throw new SpeciesError; }
-  }
-  assertThrows(() => new MyThrowingArray().map(()=>{}), SpeciesError);
-  Object.defineProperty(MyThrowingArray.prototype, 'constructor', {
-      get() { throw new ConstructorError; }
-  });
-  assertThrows(() => new MyThrowingArray().map(()=>{}), ConstructorError);
-}
diff --git a/test/mjsunit/harmony/unicode-character-ranges.js b/test/mjsunit/harmony/unicode-character-ranges.js
deleted file mode 100644
index e4f5247..0000000
--- a/test/mjsunit/harmony/unicode-character-ranges.js
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-unicode-regexps --harmony-regexp-lookbehind
-
-function execl(expectation, regexp, subject) {
-  if (regexp instanceof String) regexp = new RegExp(regexp, "u");
-  assertEquals(expectation, regexp.exec(subject));
-}
-
-function execs(expectation, regexp_source, subject) {
-  execl(expectation, new RegExp(regexp_source, "u"), subject);
-}
-
-// Character ranges.
-execl(["A"], /[A-D]/u, "A");
-execs(["A"], "[A-D]", "A");
-execl(["ABCD"], /[A-D]+/u, "ZABCDEF");
-execs(["ABCD"], "[A-D]+", "ZABCDEF");
-
-execl(["\u{12345}"], /[\u1234-\u{12345}]/u, "\u{12345}");
-execs(["\u{12345}"], "[\u1234-\u{12345}]", "\u{12345}");
-execl(null, /[^\u1234-\u{12345}]/u, "\u{12345}");
-execs(null, "[^\u1234-\u{12345}]", "\u{12345}");
-
-execl(["\u{1234}"], /[\u1234-\u{12345}]/u, "\u{1234}");
-execs(["\u{1234}"], "[\u1234-\u{12345}]", "\u{1234}");
-execl(null, /[^\u1234-\u{12345}]/u, "\u{1234}");
-execs(null, "[^\u1234-\u{12345}]", "\u{1234}");
-
-execl(null, /[\u1234-\u{12345}]/u, "\u{1233}");
-execs(null, "[\u1234-\u{12345}]", "\u{1233}");
-execl(["\u{1233}"], /[^\u1234-\u{12345}]/u, "\u{1233}");
-execs(["\u{1233}"], "[^\u1234-\u{12345}]", "\u{1233}");
-
-execl(["\u{12346}"], /[^\u1234-\u{12345}]/u, "\u{12346}");
-execs(["\u{12346}"], "[^\u1234-\u{12345}]", "\u{12346}");
-execl(null, /[\u1234-\u{12345}]/u, "\u{12346}");
-execs(null, "[\u1234-\u{12345}]", "\u{12346}");
-
-execl(["\u{12342}"], /[\u{12340}-\u{12345}]/u, "\u{12342}");
-execs(["\u{12342}"], "[\u{12340}-\u{12345}]", "\u{12342}");
-execl(["\u{12342}"], /[\ud808\udf40-\ud808\udf45]/u, "\u{12342}");
-execs(["\u{12342}"], "[\ud808\udf40-\ud808\udf45]", "\u{12342}");
-execl(null, /[^\u{12340}-\u{12345}]/u, "\u{12342}");
-execs(null, "[^\u{12340}-\u{12345}]", "\u{12342}");
-execl(null, /[^\ud808\udf40-\ud808\udf45]/u, "\u{12342}");
-execs(null, "[^\ud808\udf40-\ud808\udf45]", "\u{12342}");
-
-execl(["\u{ffff}"], /[\u{ff80}-\u{12345}]/u, "\u{ffff}");
-execs(["\u{ffff}"], "[\u{ff80}-\u{12345}]", "\u{ffff}");
-execl(["\u{ffff}"], /[\u{ff80}-\ud808\udf45]/u, "\u{ffff}");
-execs(["\u{ffff}"], "[\u{ff80}-\ud808\udf45]", "\u{ffff}");
-execl(null, /[^\u{ff80}-\u{12345}]/u, "\u{ffff}");
-execs(null, "[^\u{ff80}-\u{12345}]", "\u{ffff}");
-execl(null, /[^\u{ff80}-\ud808\udf45]/u, "\u{ffff}");
-execs(null, "[^\u{ff80}-\ud808\udf45]", "\u{ffff}");
-
-// Lone surrogate
-execl(["\ud800"], /[^\u{ff80}-\u{12345}]/u, "\uff99\u{d800}A");
-execs(["\udc00"], "[^\u{ff80}-\u{12345}]", "\uff99\u{dc00}A");
-execl(["\udc01"], /[\u0100-\u{10ffff}]/u, "A\udc01");
-execl(["\udc03"], /[\udc01-\udc03]/u, "\ud801\udc02\udc03");
-execl(["\ud801"], /[\ud801-\ud803]/u, "\ud802\udc01\ud801");
-
-// Paired sorrogate.
-execl(null, /[^\u{ff80}-\u{12345}]/u, "\u{d800}\u{dc00}");
-execs(null, "[^\u{ff80}-\u{12345}]", "\u{d800}\u{dc00}");
-execl(["\ud800\udc00"], /[\u{ff80}-\u{12345}]/u, "\u{d800}\u{dc00}");
-execs(["\ud800\udc00"], "[\u{ff80}-\u{12345}]", "\u{d800}\u{dc00}");
-execl(["foo\u{10e6d}bar"], /foo\ud803\ude6dbar/u, "foo\u{10e6d}bar");
-
-// Lone surrogates
-execl(["\ud801\ud801"], /\ud801+/u, "\ud801\udc01\ud801\ud801");
-execl(["\udc01\udc01"], /\udc01+/u, "\ud801\ud801\udc01\udc01\udc01");
-
-execl(["\udc02\udc03A"], /\W\WA/u, "\ud801\udc01A\udc02\udc03A");
-execl(["\ud801\ud802"], /\ud801./u, "\ud801\udc01\ud801\ud802");
-execl(["\udc02\udc03A"], /[\ud800-\udfff][\ud800-\udfff]A/u,
-      "\ud801\udc01A\udc02\udc03A");
-
-// Character classes
-execl(null, /\w/u, "\ud801\udc01");
-execl(["\ud801"], /[^\w]/, "\ud801\udc01");
-execl(["\ud801\udc01"], /[^\w]/u, "\ud801\udc01");
-execl(["\ud801"], /\W/, "\ud801\udc01");
-execl(["\ud801\udc01"], /\W/u, "\ud801\udc01");
-
-execl(["\ud800X"], /.X/u, "\ud800XaX");
-execl(["aX"], /.(?<!\ud800)X/u, "\ud800XaX");
-execl(["aX"], /.(?<![\ud800-\ud900])X/u, "\ud800XaX");
-
-execl(null, /[]/u, "\u1234");
-execl(["0abc"], /[^]abc/u, "0abc");
-execl(["\u1234abc"], /[^]abc/u, "\u1234abc");
-execl(["\u{12345}abc"], /[^]abc/u, "\u{12345}abc");
-
-execl(null, /[\u{0}-\u{1F444}]/u, "\ud83d\udfff");
-
-// Backward matches of lone surrogates.
-execl(["B", "\ud803A"], /(?<=([\ud800-\ud900]A))B/u,
-      "\ud801\udc00AB\udc00AB\ud802\ud803AB");
-execl(["B", "\udc00A"], /(?<=([\ud800-\u{10300}]A))B/u,
-       "\ud801\udc00AB\udc00AB\ud802\ud803AB");
-execl(["B", "\udc11A"], /(?<=([\udc00-\udd00]A))B/u,
-      "\ud801\udc00AB\udc11AB\ud802\ud803AB");
-execl(["X", "\ud800C"], /(?<=(\ud800\w))X/u,
-      "\ud800\udc00AX\udc11BX\ud800\ud800CX");
-execl(["C", "\ud800\ud800"], /(?<=(\ud800.))\w/u,
-      "\ud800\udc00AX\udc11BX\ud800\ud800CX");
-execl(["X", "\udc01C"], /(?<=(\udc01\w))X/u,
-      "\ud800\udc01AX\udc11BX\udc01\udc01CX");
-execl(["C", "\udc01\udc01"], /(?<=(\udc01.))./u,
-      "\ud800\udc01AX\udc11BX\udc01\udc01CX");
-
-var L = "\ud800";
-var T = "\udc00";
-var X = "X";
-
-// Test string contains only match.
-function testw(expect, src, subject) {
-  var re = new RegExp("^" + src + "$", "u");
-  assertEquals(expect, re.test(subject));
-}
-
-// Test string starts with match.
-function tests(expect, src, subject) {
-  var re = new RegExp("^" + src, "u");
-  assertEquals(expect, re.test(subject));
-}
-
-testw(true, X, X);
-testw(true, L, L);
-testw(true, T, T);
-testw(true, L + T, L + T);
-testw(true, T + L, T + L);
-testw(false, T, L + T);
-testw(false, L, L + T);
-testw(true, ".(?<=" + L + ")", L);
-testw(true, ".(?<=" + T + ")", T);
-testw(true, ".(?<=" + L + T + ")", L + T);
-testw(true, ".(?<=" + L + T + ")", L + T);
-tests(true, ".(?<=" + T + ")", T + L);
-tests(false, ".(?<=" + L + ")", L + T);
-tests(false, ".(?<=" + T + ")", L + T);
-tests(true, "..(?<=" + T + ")", T + T + L);
-tests(true, "..(?<=" + T + ")", X + T + L);
-tests(true, "...(?<=" + L + ")", X + T + L);
-tests(false, "...(?<=" + T + ")", X + L + T)
-tests(true, "..(?<=" + L + T + ")", X + L + T)
-tests(true, "..(?<=" + L + T + "(?<=" + L + T + "))", X + L + T);
-tests(false, "..(?<=" + L + "(" + T + "))", X + L + T);
-tests(false, ".*" + L, X + L + T);
-tests(true, ".*" + L, X + L + L + T);
-tests(false, ".*" + L, X + L + T + L + T);
-tests(false, ".*" + T, X + L + T + L + T);
-tests(true, ".*" + T, X + L + T + T + L + T);
diff --git a/test/mjsunit/harmony/unicode-escapes-in-regexps.js b/test/mjsunit/harmony/unicode-escapes-in-regexps.js
deleted file mode 100644
index 7ea6f62..0000000
--- a/test/mjsunit/harmony/unicode-escapes-in-regexps.js
+++ /dev/null
@@ -1,287 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// ES6 extends the \uxxxx escape and also allows \u{xxxxx}.
-
-// Flags: --harmony-unicode-regexps
-
-function testRegexpHelper(r) {
-  assertTrue(r.test("foo"));
-  assertTrue(r.test("boo"));
-  assertFalse(r.test("moo"));
-}
-
-
-(function TestUnicodeEscapes() {
-  testRegexpHelper(/(\u0066|\u0062)oo/);
-  testRegexpHelper(/(\u0066|\u0062)oo/u);
-  testRegexpHelper(/(\u{0066}|\u{0062})oo/u);
-  testRegexpHelper(/(\u{66}|\u{000062})oo/u);
-
-  // Note that we need \\ inside a string, otherwise it's interpreted as a
-  // unicode escape inside a string.
-  testRegexpHelper(new RegExp("(\\u0066|\\u0062)oo"));
-  testRegexpHelper(new RegExp("(\\u0066|\\u0062)oo", "u"));
-  testRegexpHelper(new RegExp("(\\u{0066}|\\u{0062})oo", "u"));
-  testRegexpHelper(new RegExp("(\\u{66}|\\u{000062})oo", "u"));
-
-  // Though, unicode escapes via strings should work too.
-  testRegexpHelper(new RegExp("(\u0066|\u0062)oo"));
-  testRegexpHelper(new RegExp("(\u0066|\u0062)oo", "u"));
-  testRegexpHelper(new RegExp("(\u{0066}|\u{0062})oo", "u"));
-  testRegexpHelper(new RegExp("(\u{66}|\u{000062})oo", "u"));
-})();
-
-
-(function TestUnicodeEscapesInCharacterClasses() {
-  testRegexpHelper(/[\u0062-\u0066]oo/);
-  testRegexpHelper(/[\u0062-\u0066]oo/u);
-  testRegexpHelper(/[\u{0062}-\u{0066}]oo/u);
-  testRegexpHelper(/[\u{62}-\u{00000066}]oo/u);
-
-  // Note that we need \\ inside a string, otherwise it's interpreted as a
-  // unicode escape inside a string.
-  testRegexpHelper(new RegExp("[\\u0062-\\u0066]oo"));
-  testRegexpHelper(new RegExp("[\\u0062-\\u0066]oo", "u"));
-  testRegexpHelper(new RegExp("[\\u{0062}-\\u{0066}]oo", "u"));
-  testRegexpHelper(new RegExp("[\\u{62}-\\u{00000066}]oo", "u"));
-
-  // Though, unicode escapes via strings should work too.
-  testRegexpHelper(new RegExp("[\u0062-\u0066]oo"));
-  testRegexpHelper(new RegExp("[\u0062-\u0066]oo", "u"));
-  testRegexpHelper(new RegExp("[\u{0062}-\u{0066}]oo", "u"));
-  testRegexpHelper(new RegExp("[\u{62}-\u{00000066}]oo", "u"));
-})();
-
-
-(function TestBraceEscapesWithoutUnicodeFlag() {
-  // \u followed by illegal escape will be parsed as u. {x} will be the
-  // character count.
-  function helper1(r) {
-    assertFalse(r.test("fbar"));
-    assertFalse(r.test("fubar"));
-    assertTrue(r.test("fuubar"));
-    assertFalse(r.test("fuuubar"));
-  }
-  helper1(/f\u{2}bar/);
-  helper1(new RegExp("f\\u{2}bar"));
-
-  function helper2(r) {
-    assertFalse(r.test("fbar"));
-    assertTrue(r.test("fubar"));
-    assertTrue(r.test("fuubar"));
-    assertFalse(r.test("fuuubar"));
-  }
-
-  helper2(/f\u{1,2}bar/);
-  helper2(new RegExp("f\\u{1,2}bar"));
-
-  function helper3(r) {
-    assertTrue(r.test("u"));
-    assertTrue(r.test("{"));
-    assertTrue(r.test("2"));
-    assertTrue(r.test("}"));
-    assertFalse(r.test("q"));
-    assertFalse(r.test("("));
-    assertFalse(r.test(")"));
-  }
-  helper3(/[\u{2}]/);
-  helper3(new RegExp("[\\u{2}]"));
-})();
-
-
-(function TestInvalidEscapes() {
-  // Without the u flag, invalid unicode escapes and other invalid escapes are
-  // treated as identity escapes.
-  function helper1(r) {
-    assertTrue(r.test("firstuxz89second"));
-  }
-  helper1(/first\u\x\z\8\9second/);
-  helper1(new RegExp("first\\u\\x\\z\\8\\9second"));
-
-  function helper2(r) {
-    assertTrue(r.test("u"));
-    assertTrue(r.test("x"));
-    assertTrue(r.test("z"));
-    assertTrue(r.test("8"));
-    assertTrue(r.test("9"));
-    assertFalse(r.test("q"));
-    assertFalse(r.test("7"));
-  }
-  helper2(/[\u\x\z\8\9]/);
-  helper2(new RegExp("[\\u\\x\\z\\8\\9]"));
-
-  // However, with the u flag, these are treated as invalid escapes.
-  assertThrows("/\\u/u", SyntaxError);
-  assertThrows("/\\u12/u", SyntaxError);
-  assertThrows("/\\ufoo/u", SyntaxError);
-  assertThrows("/\\x/u", SyntaxError);
-  assertThrows("/\\xfoo/u", SyntaxError);
-  assertThrows("/\\z/u", SyntaxError);
-  assertThrows("/\\8/u", SyntaxError);
-  assertThrows("/\\9/u", SyntaxError);
-
-  assertThrows("new RegExp('\\\\u', 'u')", SyntaxError);
-  assertThrows("new RegExp('\\\\u12', 'u')", SyntaxError);
-  assertThrows("new RegExp('\\\\ufoo', 'u')", SyntaxError);
-  assertThrows("new RegExp('\\\\x', 'u')", SyntaxError);
-  assertThrows("new RegExp('\\\\xfoo', 'u')", SyntaxError);
-  assertThrows("new RegExp('\\\\z', 'u')", SyntaxError);
-  assertThrows("new RegExp('\\\\8', 'u')", SyntaxError);
-  assertThrows("new RegExp('\\\\9', 'u')", SyntaxError);
-})();
-
-
-(function TestTooBigHexEscape() {
-  // The hex number inside \u{} has a maximum value.
-  /\u{10ffff}/u
-  new RegExp("\\u{10ffff}", "u")
-  assertThrows("/\\u{110000}/u", SyntaxError);
-  assertThrows("new RegExp('\\\\u{110000}', 'u')", SyntaxError);
-
-  // Without the u flag, they're of course fine ({x} is the count).
-  /\u{110000}/
-  new RegExp("\\u{110000}")
-})();
-
-
-(function TestSyntaxEscapes() {
-  // Syntax escapes work the same with or without the u flag.
-  function helper(r) {
-    assertTrue(r.test("foo[bar"));
-    assertFalse(r.test("foo]bar"));
-  }
-  helper(/foo\[bar/);
-  helper(new RegExp("foo\\[bar"));
-  helper(/foo\[bar/u);
-  helper(new RegExp("foo\\[bar", "u"));
-})();
-
-
-(function TestUnicodeSurrogates() {
-  // U+10E6D corresponds to the surrogate pair [U+D803, U+DE6D].
-  function helper(r) {
-    assertTrue(r.test("foo\u{10e6d}bar"));
-  }
-  helper(/foo\ud803\ude6dbar/u);
-  helper(new RegExp("foo\\ud803\\ude6dbar", "u"));
-})();
-
-
-(function AllFlags() {
-  // Test that we can pass all possible regexp flags and they work properly.
-  function helper1(r) {
-    assertTrue(r.global);
-    assertTrue(r.ignoreCase);
-    assertTrue(r.multiline);
-    assertTrue(r.sticky);
-    assertTrue(r.unicode);
-  }
-
-  helper1(/foo/gimyu);
-  helper1(new RegExp("foo", "gimyu"));
-
-  function helper2(r) {
-    assertFalse(r.global);
-    assertFalse(r.ignoreCase);
-    assertFalse(r.multiline);
-    assertFalse(r.sticky);
-    assertFalse(r.unicode);
-  }
-
-  helper2(/foo/);
-  helper2(new RegExp("foo"));
-})();
-
-
-(function DuplicatedFlags() {
-  // Test that duplicating the u flag is not allowed.
-  assertThrows("/foo/ugu");
-  assertThrows("new RegExp('foo', 'ugu')");
-})();
-
-
-(function ToString() {
-  // Test that the u flag is included in the string representation of regexps.
-  function helper(r) {
-    assertEquals(r.toString(), "/foo/u");
-  }
-  helper(/foo/u);
-  helper(new RegExp("foo", "u"));
-})();
-
-// Non-BMP patterns.
-// Single character atom.
-assertTrue(new RegExp("\u{12345}", "u").test("\u{12345}"));
-assertTrue(/\u{12345}/u.test("\u{12345}"));
-assertTrue(new RegExp("\u{12345}", "u").test("\ud808\udf45"));
-assertTrue(/\u{12345}/u.test("\ud808\udf45"));
-assertFalse(new RegExp("\u{12345}", "u").test("\udf45"));
-assertFalse(/\u{12345}/u.test("\udf45"));
-
-// Multi-character atom.
-assertTrue(new RegExp("\u{12345}\u{23456}", "u").test("a\u{12345}\u{23456}b"));
-assertTrue(/\u{12345}\u{23456}/u.test("b\u{12345}\u{23456}c"));
-assertFalse(new RegExp("\u{12345}\u{23456}", "u").test("a\udf45\u{23456}b"));
-assertFalse(/\u{12345}\u{23456}/u.test("b\udf45\u{23456}c"));
-
-// Disjunction.
-assertTrue(new RegExp("\u{12345}(?:\u{23456})", "u").test(
-    "a\u{12345}\u{23456}b"));
-assertTrue(/\u{12345}(?:\u{23456})/u.test("b\u{12345}\u{23456}c"));
-assertFalse(new RegExp("\u{12345}(?:\u{23456})", "u").test(
-    "a\udf45\u{23456}b"));
-assertFalse(/\u{12345}(?:\u{23456})/u.test("b\udf45\u{23456}c"));
-
-// Alternative.
-assertTrue(new RegExp("\u{12345}|\u{23456}", "u").test("a\u{12345}b"));
-assertTrue(/\u{12345}|\u{23456}/u.test("b\u{23456}c"));
-assertFalse(new RegExp("\u{12345}|\u{23456}", "u").test("a\udf45\ud84db"));
-assertFalse(/\u{12345}|\u{23456}/u.test("b\udf45\ud808c"));
-
-// Capture.
-assertTrue(new RegExp("(\u{12345}|\u{23456}).\\1", "u").test(
-    "\u{12345}b\u{12345}"));
-assertTrue(/(\u{12345}|\u{23456}).\1/u.test("\u{12345}b\u{12345}"));
-assertFalse(new RegExp("(\u{12345}|\u{23456}).\\1", "u").test(
-    "\u{12345}b\u{23456}"));
-assertFalse(/(\u{12345}|\u{23456}).\1/u.test("\u{12345}b\u{23456}"));
-
-// Quantifier.
-assertTrue(new RegExp("\u{12345}{3}", "u").test("\u{12345}\u{12345}\u{12345}"));
-assertTrue(/\u{12345}{3}/u.test("\u{12345}\u{12345}\u{12345}"));
-assertTrue(new RegExp("\u{12345}{3}").test("\u{12345}\udf45\udf45"));
-assertFalse(/\ud808\udf45{3}/u.test("\u{12345}\udf45\udf45"));
-assertTrue(/\ud808\udf45{3}/u.test("\u{12345}\u{12345}\u{12345}"));
-assertFalse(new RegExp("\u{12345}{3}", "u").test("\u{12345}\udf45\udf45"));
-assertFalse(/\u{12345}{3}/u.test("\u{12345}\udf45\udf45"));
-
-// Literal surrogates.
-assertEquals(["\u{10000}\u{10000}"],
-             new RegExp("\ud800\udc00+", "u").exec("\u{10000}\u{10000}"));
-assertEquals(["\u{10000}\u{10000}"],
-             new RegExp("\\ud800\\udc00+", "u").exec("\u{10000}\u{10000}"));
-
-assertEquals(["\u{10003}\u{50001}"],
-             new RegExp("[\\ud800\\udc03-\\ud900\\udc01\]+", "u").exec(
-                 "\u{10003}\u{50001}"));
-assertEquals(["\u{10003}\u{50001}"],
-             new RegExp("[\ud800\udc03-\u{50001}\]+", "u").exec(
-                 "\u{10003}\u{50001}"));
-
-// Unicode escape sequences to represent a non-BMP character cannot have
-// mixed notation, and must follow the rules for RegExpUnicodeEscapeSequence.
-assertThrows(() => new RegExp("[\\ud800\udc03-\ud900\\udc01\]+", "u"));
-assertThrows(() => new RegExp("[\\ud800\udc03-\ud900\\udc01\]+", "u"));
-assertNull(new RegExp("\\ud800\udc00+", "u").exec("\u{10000}\u{10000}"));
-assertNull(new RegExp("\ud800\\udc00+", "u").exec("\u{10000}\u{10000}"));
-
-assertNull(new RegExp("[\\ud800\udc00]", "u").exec("\u{10000}"));
-assertNull(new RegExp("[\\{ud800}\udc00]", "u").exec("\u{10000}"));
-assertNull(new RegExp("[\ud800\\udc00]", "u").exec("\u{10000}"));
-assertNull(new RegExp("[\ud800\\{udc00}]", "u").exec("\u{10000}"));
-
-assertNull(/\u{d800}\u{dc00}+/u.exec("\ud800\udc00\udc00"));
-assertNull(/\ud800\u{dc00}+/u.exec("\ud800\udc00\udc00"));
-assertNull(/\u{d800}\udc00+/u.exec("\ud800\udc00\udc00"));
diff --git a/test/mjsunit/harmony/unicode-regexp-backrefs.js b/test/mjsunit/harmony/unicode-regexp-backrefs.js
deleted file mode 100644
index e02301b..0000000
--- a/test/mjsunit/harmony/unicode-regexp-backrefs.js
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-unicode-regexps --harmony-regexp-lookbehind
-
-// Back reference does not end in the middle of a surrogate pair.
-function replace(string) {
-  return string.replace(/L/g, "\ud800")
-               .replace(/l/g, "\ud801")
-               .replace(/T/g, "\udc00")
-               .replace(/\./g, "[^]");
-}
-
-function test(expectation, regexp_source, subject) {
-  if (expectation !== null) expectation = expectation.map(replace);
-  subject = replace(subject);
-  regexp_source = replace(regexp_source);
-  assertEquals(expectation, new RegExp(regexp_source, "u").exec(subject));
-}
-
-// Back reference does not end in the middle of a surrogate pair.
-test(null, "(L)\\1", "LLT");
-test(["LLTLl", "L", "l"], "(L).*\\1(.)", "LLTLl");
-test(null, "(aL).*\\1", "aLaLT");
-test(["aLaLTaLl", "aL", "l"], "(aL).*\\1(.)", "aLaLTaLl");
-
-var s = "TabcLxLTabcLxTabcLTyTabcLz";
-test([s, "TabcL", "z"], "([^x]+).*\\1(.)", s);
-
-// Back reference does not start in the middle of a surrogate pair.
-test(["TLTabTc", "T", "c"], "(T).*\\1(.)", "TLTabTc");
-
-// Lookbehinds.
-test(null, "(?<=\\1(T)x)", "LTTx");
-test(["", "b", "T"], "(?<=(.)\\2.*(T)x)", "bTaLTTx");
-test(null, "(?<=\\1.*(L)x)", "LTLx");
-test(["", "b", "L"], "(?<=(.)\\2.*(L)x)", "bLaLTLx");
-
-
-test(null, "([^x]+)x*\\1", "LxLT");
-test(null, "([^x]+)x*\\1", "TxLT");
-test(null, "([^x]+)x*\\1", "LTxL");
-test(null, "([^x]+)x*\\1", "LTxT");
-test(null, "([^x]+)x*\\1", "xLxLT");
-test(null, "([^x]+)x*\\1", "xTxLT");
-test(null, "([^x]+)x*\\1", "xLTxL");
-test(null, "([^x]+)x*\\1", "xLTxT");
-test(null, "([^x]+)x*\\1", "xxxLxxLTxx");
-test(null, "([^x]+)x*\\1", "xxxTxxLTxx");
-test(null, "([^x]+)x*\\1", "xxxLTxxLxx");
-test(null, "([^x]+)x*\\1", "xxxLTxxTxx");
-test(["LTTxxLTT", "LTT"], "([^x]+)x*\\1", "xxxLTTxxLTTxx");
diff --git a/test/mjsunit/harmony/unicode-regexp-ignore-case-noi18n.js b/test/mjsunit/harmony/unicode-regexp-ignore-case-noi18n.js
deleted file mode 100644
index a4cb9dc..0000000
--- a/test/mjsunit/harmony/unicode-regexp-ignore-case-noi18n.js
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-unicode-regexps
-
-// Non-unicode use toUpperCase mappings.
-assertFalse(/[\u00e5]/i.test("\u212b"));
-assertFalse(/[\u212b]/i.test("\u00e5\u1234"));
-assertFalse(/[\u212b]/i.test("\u00e5"));
-
-assertTrue("\u212b".toLowerCase() == "\u00e5");
-assertTrue("\u00c5".toLowerCase() == "\u00e5");
-assertTrue("\u00e5".toUpperCase() == "\u00c5");
-
-// Unicode uses case folding mappings.
-assertFalse(/\u00e5/ui.test("\u212b"));
-assertTrue(/\u00e5/ui.test("\u00c5"));
-assertTrue(/\u00e5/ui.test("\u00e5"));
-assertFalse(/\u00e5/ui.test("\u212b"));
-assertTrue(/\u00c5/ui.test("\u00e5"));
-assertFalse(/\u00c5/ui.test("\u212b"));
-assertTrue(/\u00c5/ui.test("\u00c5"));
-assertFalse(/\u212b/ui.test("\u00c5"));
-assertFalse(/\u212b/ui.test("\u00e5"));
-assertTrue(/\u212b/ui.test("\u212b"));
-
-// Non-BMP.
-assertFalse(/\u{10400}/i.test("\u{10428}"));
-assertFalse(/\u{10400}/ui.test("\u{10428}"));
-assertFalse(/\ud801\udc00/ui.test("\u{10428}"));
-assertFalse(/[\u{10428}]/ui.test("\u{10400}"));
-assertFalse(/[\ud801\udc28]/ui.test("\u{10400}"));
-assertEquals(["\uff21\u{10400}"],
-             /[\uff40-\u{10428}]+/ui.exec("\uff21\u{10400}abc"));
-assertEquals(["abc"], /[^\uff40-\u{10428}]+/ui.exec("\uff21\u{10400}abc\uff23"));
-assertEquals(["\uff53\u24bb"],
-             /[\u24d5-\uff33]+/ui.exec("\uff54\uff53\u24bb\u24ba"));
-
-// Full mappings are ignored.
-assertFalse(/\u00df/ui.test("SS"));
-assertFalse(/\u1f8d/ui.test("\u1f05\u03b9"));
-
-// Simple mappings.
-assertFalse(/\u1f8d/ui.test("\u1f85"));
-
-// Common mappings.
-assertTrue(/\u1f6b/ui.test("\u1f63"));
-
-// Back references.
-assertNull(/(.)\1\1/ui.exec("\u00e5\u212b\u00c5"));
-assertNull(/(.)\1/ui.exec("\u{118aa}\u{118ca}"));
-
-
-// Non-Latin1 maps to Latin1.
-assertNull(/^\u017F/ui.exec("s"));
-assertNull(/^\u017F/ui.exec("s\u1234"));
-assertNull(/^a[\u017F]/ui.exec("as"));
-assertNull(/^a[\u017F]/ui.exec("as\u1234"));
diff --git a/test/mjsunit/harmony/unicode-regexp-ignore-case.js b/test/mjsunit/harmony/unicode-regexp-ignore-case.js
deleted file mode 100644
index 291b866..0000000
--- a/test/mjsunit/harmony/unicode-regexp-ignore-case.js
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-unicode-regexps
-
-// Non-unicode use toUpperCase mappings.
-assertFalse(/[\u00e5]/i.test("\u212b"));
-assertFalse(/[\u212b]/i.test("\u00e5\u1234"));
-assertFalse(/[\u212b]/i.test("\u00e5"));
-
-assertTrue("\u212b".toLowerCase() == "\u00e5");
-assertTrue("\u00c5".toLowerCase() == "\u00e5");
-assertTrue("\u00e5".toUpperCase() == "\u00c5");
-
-// Unicode uses case folding mappings.
-assertTrue(/\u00e5/ui.test("\u212b"));
-assertTrue(/\u00e5/ui.test("\u00c5"));
-assertTrue(/\u00e5/ui.test("\u00e5"));
-assertTrue(/\u00e5/ui.test("\u212b"));
-assertTrue(/\u00c5/ui.test("\u00e5"));
-assertTrue(/\u00c5/ui.test("\u212b"));
-assertTrue(/\u00c5/ui.test("\u00c5"));
-assertTrue(/\u212b/ui.test("\u00c5"));
-assertTrue(/\u212b/ui.test("\u00e5"));
-assertTrue(/\u212b/ui.test("\u212b"));
-
-// Non-BMP.
-assertFalse(/\u{10400}/i.test("\u{10428}"));
-assertTrue(/\u{10400}/ui.test("\u{10428}"));
-assertTrue(/\ud801\udc00/ui.test("\u{10428}"));
-assertTrue(/[\u{10428}]/ui.test("\u{10400}"));
-assertTrue(/[\ud801\udc28]/ui.test("\u{10400}"));
-assertEquals(["\uff21\u{10400}"],
-             /[\uff40-\u{10428}]+/ui.exec("\uff21\u{10400}abc"));
-assertEquals(["abc"], /[^\uff40-\u{10428}]+/ui.exec("\uff21\u{10400}abc\uff23"));
-assertEquals(["\uff53\u24bb"],
-             /[\u24d5-\uff33]+/ui.exec("\uff54\uff53\u24bb\u24ba"));
-
-// Full mappings are ignored.
-assertFalse(/\u00df/ui.test("SS"));
-assertFalse(/\u1f8d/ui.test("\u1f05\u03b9"));
-
-// Simple mappings work.
-assertTrue(/\u1f8d/ui.test("\u1f85"));
-
-// Common mappings work.
-assertTrue(/\u1f6b/ui.test("\u1f63"));
-
-// Back references.
-assertEquals(["\u00e5\u212b\u00c5", "\u00e5"],
-             /(.)\1\1/ui.exec("\u00e5\u212b\u00c5"));
-assertEquals(["\u{118aa}\u{118ca}", "\u{118aa}"],
-             /(.)\1/ui.exec("\u{118aa}\u{118ca}"));
-
-// Misc.
-assertTrue(/\u00e5\u00e5\u00e5/ui.test("\u212b\u00e5\u00c5"));
-assertTrue(/AB\u{10400}/ui.test("ab\u{10428}"));
-
-// Non-Latin1 maps to Latin1.
-assertEquals(["s"], /^\u017F/ui.exec("s"));
-assertEquals(["s"], /^\u017F/ui.exec("s\u1234"));
-assertEquals(["as"], /^a[\u017F]/ui.exec("as"));
-assertEquals(["as"], /^a[\u017F]/ui.exec("as\u1234"));
diff --git a/test/mjsunit/harmony/unicode-regexp-last-index.js b/test/mjsunit/harmony/unicode-regexp-last-index.js
deleted file mode 100644
index 4a075d4..0000000
--- a/test/mjsunit/harmony/unicode-regexp-last-index.js
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-unicode-regexps --harmony-regexp-lookbehind
-
-var r = /./ug;
-assertEquals(["\ud800\udc00"], r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(2, r.lastIndex);
-r.lastIndex = 1;
-assertEquals(["\ud800\udc00"], r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(2, r.lastIndex);
-assertEquals(["\ud801\udc01"], r.exec("\ud800\udc00\ud801\udc01"));
-r.lastIndex = 3;
-assertEquals(["\ud801\udc01"], r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(4, r.lastIndex);
-r.lastIndex = 4;
-assertNull(r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(0, r.lastIndex);
-r.lastIndex = 5;
-assertNull(r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(0, r.lastIndex);
-
-r.lastIndex = 3;
-assertEquals(["\ud802"], r.exec("\ud800\udc00\ud801\ud802"));
-r.lastIndex = 4;
-assertNull(r.exec("\ud800\udc00\ud801\ud802"));
-
-r = /./g;
-assertEquals(["\ud800"], r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(1, r.lastIndex);
-assertEquals(["\udc00"], r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(2, r.lastIndex);
-assertEquals(["\ud801"], r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(3, r.lastIndex);
-assertEquals(["\udc01"], r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(4, r.lastIndex);
-assertNull(r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(0, r.lastIndex);
-r.lastIndex = 1;
-assertEquals(["\udc00"], r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(2, r.lastIndex);
-
-// ------------------------
-
-r = /^./ug;
-assertEquals(["\ud800\udc00"], r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(2, r.lastIndex);
-r.lastIndex = 1;
-assertEquals(["\ud800\udc00"], r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(2, r.lastIndex);
-assertNull(r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(0, r.lastIndex);
-r.lastIndex = 3;
-assertNull(r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(0, r.lastIndex);
-r.lastIndex = 4;
-assertNull(r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(0, r.lastIndex);
-r.lastIndex = 5;
-assertNull(r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(0, r.lastIndex);
-
-r = /^./g;
-assertEquals(["\ud800"], r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(1, r.lastIndex);
-assertNull(r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(0, r.lastIndex);
-r.lastIndex = 3;
-assertNull(r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(0, r.lastIndex);
-
-//------------------------
-
-r = /(?:(^.)|.)/ug;
-assertEquals(["\ud800\udc00", "\ud800\udc00"],
-             r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(2, r.lastIndex);
-r.lastIndex = 1;
-assertEquals(["\ud800\udc00", "\ud800\udc00"],
-             r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(2, r.lastIndex);
-assertEquals(["\ud801\udc01", undefined], r.exec("\ud800\udc00\ud801\udc01"));
-r.lastIndex = 3;
-assertEquals(["\ud801\udc01", undefined], r.exec("\ud800\udc00\ud801\udc01"));
-r.lastIndex = 4;
-assertNull(r.exec("\ud800\udc00\ud801\udc01"));
-r.lastIndex = 5;
-assertNull(r.exec("\ud800\udc00\ud801\udc01"));
-
-r.lastIndex = 3;
-assertEquals(["\ud802", undefined], r.exec("\ud800\udc00\ud801\ud802"));
-r.lastIndex = 4;
-assertNull(r.exec("\ud800\udc00\ud801\ud802"));
-
-r = /(?:(^.)|.)/g;
-assertEquals(["\ud800", "\ud800"],
-    r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(1, r.lastIndex);
-assertEquals(["\udc00", undefined], r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(2, r.lastIndex);
-r.lastIndex = 3;
-assertEquals(["\udc01", undefined], r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(4, r.lastIndex);
diff --git a/test/mjsunit/harmony/unicode-regexp-restricted-syntax.js b/test/mjsunit/harmony/unicode-regexp-restricted-syntax.js
deleted file mode 100644
index d129cc3..0000000
--- a/test/mjsunit/harmony/unicode-regexp-restricted-syntax.js
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-unicode-regexps
-
-// test262/data/test/language/literals/regexp/u-dec-esc
-assertThrows("/\\1/u", SyntaxError);
-// test262/language/literals/regexp/u-invalid-char-range-a
-assertThrows("/[\\w-a]/u", SyntaxError);
-// test262/language/literals/regexp/u-invalid-char-range-b
-assertThrows("/[a-\\w]/u", SyntaxError);
-// test262/language/literals/regexp/u-invalid-char-esc
-assertThrows("/\\c/u", SyntaxError);
-assertThrows("/\\c0/u", SyntaxError);
-// test262/built-ins/RegExp/unicode_restricted_quantifiable_assertion
-assertThrows("/(?=.)*/u", SyntaxError);
-// test262/built-ins/RegExp/unicode_restricted_octal_escape
-assertThrows("/[\\1]/u", SyntaxError);
-assertThrows("/\\00/u", SyntaxError);
-assertThrows("/\\09/u", SyntaxError);
-// test262/built-ins/RegExp/unicode_restricted_identity_escape_alpha
-assertThrows("/[\\c]/u", SyntaxError);
-// test262/built-ins/RegExp/unicode_restricted_identity_escape_c
-assertThrows("/[\\c0]/u", SyntaxError);
-// test262/built-ins/RegExp/unicode_restricted_incomple_quantifier
-assertThrows("/a{/u", SyntaxError);
-assertThrows("/a{1,/u", SyntaxError);
-assertThrows("/{/u", SyntaxError);
-assertThrows("/}/u", SyntaxError);
-// test262/data/test/built-ins/RegExp/unicode_restricted_brackets
-assertThrows("/]/u", SyntaxError);
-// test262/built-ins/RegExp/unicode_identity_escape
-/\//u;
-
-// escaped \0 is allowed inside a character class.
-assertEquals(["\0"], /[\0]/u.exec("\0"));
-// unless it is followed by another digit.
-assertThrows("/[\\00]/u", SyntaxError);
-assertThrows("/[\\01]/u", SyntaxError);
-assertThrows("/[\\09]/u", SyntaxError);
-assertEquals(["\u{0}1\u{0}a\u{0}"], /[1\0a]+/u.exec("b\u{0}1\u{0}a\u{0}2"));
-// escaped \- is allowed inside a character class.
-assertEquals(["-"], /[a\-z]/u.exec("12-34"));
diff --git a/test/mjsunit/harmony/unicode-regexp-unanchored-advance.js b/test/mjsunit/harmony/unicode-regexp-unanchored-advance.js
deleted file mode 100644
index 97960e1..0000000
--- a/test/mjsunit/harmony/unicode-regexp-unanchored-advance.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-unicode-regexps
-
-var s = "a".repeat(1E7) + "\u1234";
-assertEquals(["\u1234", "\u1234"], /(\u1234)/u.exec(s));
diff --git a/test/mjsunit/harmony/unicode-regexp-zero-length.js b/test/mjsunit/harmony/unicode-regexp-zero-length.js
deleted file mode 100644
index bbc17dc..0000000
--- a/test/mjsunit/harmony/unicode-regexp-zero-length.js
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-unicode-regexps
-
-var L = "\ud800";
-var T = "\udc00";
-var x = "x";
-
-var r = /()/g;  // Global, but not unicode.
-// Zero-length matches do not advance lastIndex.
-assertEquals(["", ""], r.exec(L + T + L + T));
-assertEquals(0, r.lastIndex);
-r.lastIndex = 1;
-assertEquals(["", ""], r.exec(L + T + L + T));
-assertEquals(1, r.lastIndex);
-
-var u = /()/ug;  // Global and unicode.
-// Zero-length matches do not advance lastIndex.
-assertEquals(["", ""], u.exec(L + T + L + T));
-assertEquals(0, u.lastIndex);
-u.lastIndex = 1;
-assertEquals(["", ""], u.exec(L + T + L + T));
-assertEquals(0, u.lastIndex);
-
-// However, with repeating matches, lastIndex does not matter.
-// We do advance from match to match.
-r.lastIndex = 2;
-assertEquals(x + L + x + T + x + L + x + T + x,
-             (L + T + L + T).replace(r, "x"));
-
-// With unicode flag, we advance code point by code point.
-u.lastIndex = 3;
-assertEquals(x + L + T + x + L + T + x,
-             (L + T + L + T).replace(u, "x"));
-
-// Test that exhausting the global match cache is fine.
-assertEquals((x + L + T).repeat(1000) + x,
-             (L + T).repeat(1000).replace(u, "x"));
-
-// Same thing for RegExp.prototype.match.
-r.lastIndex = 1;
-assertEquals(["","","","",""], (L + T + L + T).match(r));
-r.lastIndex = 2;
-assertEquals(["","","","",""], (L + T + L + T).match(r));
-
-u.lastIndex = 1;
-assertEquals(["","",""], (L + T + L + T).match(u));
-u.lastIndex = 2;
-assertEquals(["","",""], (L + T + L + T).match(u));
-
-var expected = [];
-for (var i = 0; i <= 1000; i++) expected.push("");
-assertEquals(expected, (L + T).repeat(1000).match(u));
-
-// Also test RegExp.prototype.@@split.
-assertEquals(["\u{12345}"], "\u{12345}".split(/(?:)/u));