Merge V8 5.2.361.47  DO NOT MERGE

https://chromium.googlesource.com/v8/v8/+/5.2.361.47

FPIIM-449

Change-Id: Ibec421b85a9b88cb3a432ada642e469fe7e78346
(cherry picked from commit bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8)
diff --git a/test/mjsunit/arguments.js b/test/mjsunit/arguments.js
index 26eb389..97ec7cc 100644
--- a/test/mjsunit/arguments.js
+++ b/test/mjsunit/arguments.js
@@ -204,3 +204,70 @@
   }
   assertTrue(%HasSloppyArgumentsElements(a));
 })();
+
+(function testDeleteArguments() {
+  function f() { return arguments };
+  var args = f(1, 2);
+  assertEquals(1, args[0]);
+  assertEquals(2, args[1]);
+  assertEquals(2, args.length);
+
+  delete args[0];
+  assertEquals(undefined, args[0]);
+  assertEquals(2, args[1]);
+  assertEquals(2, args.length);
+
+  delete args[1];
+  assertEquals(undefined, args[0]);
+  assertEquals(undefined, args[1]);
+  assertEquals(2, args.length);
+})();
+
+(function testDeleteFastSloppyArguments() {
+  function f(a) { return arguments };
+  var args = f(1, 2);
+  assertEquals(1, args[0]);
+  assertEquals(2, args[1]);
+  assertEquals(2, args.length);
+
+  delete args[0];
+  assertEquals(undefined, args[0]);
+  assertEquals(2, args[1]);
+  assertEquals(2, args.length);
+
+  delete args[1];
+  assertEquals(undefined, args[0]);
+  assertEquals(undefined, args[1]);
+  assertEquals(2, args.length);
+})();
+
+(function testDeleteSlowSloppyArguments() {
+  var key = 10000;
+  function f(a) {
+    arguments[key] = key;
+    return arguments
+  };
+  var args = f(1, 2);
+  assertEquals(1, args[0]);
+  assertEquals(2, args[1]);
+  assertEquals(key, args[key]);
+  assertEquals(2, args.length);
+
+  delete args[0];
+  assertEquals(undefined, args[0]);
+  assertEquals(2, args[1]);
+  assertEquals(key, args[key]);
+  assertEquals(2, args.length);
+
+  delete args[1];
+  assertEquals(undefined, args[0]);
+  assertEquals(undefined, args[1]);
+  assertEquals(key, args[key]);
+  assertEquals(2, args.length);
+
+  delete args[key];
+  assertEquals(undefined, args[0]);
+  assertEquals(undefined, args[1]);
+  assertEquals(undefined, args[key]);
+  assertEquals(2, args.length);
+})();
diff --git a/test/mjsunit/array-push.js b/test/mjsunit/array-push.js
index c87fd12..ece3319 100644
--- a/test/mjsunit/array-push.js
+++ b/test/mjsunit/array-push.js
@@ -146,3 +146,16 @@
   f(a, {});
   assertEquals(10, a.f());
 })();
+
+
+(function testDoubleArrayPush() {
+  var a = [];
+  var max = 1000;
+  for (var i = 0; i < max; i++) {
+    a.push(i + 0.1);
+  }
+  assertEquals(max, a.length);
+  for (var i = 0; i < max; i++) {
+    assertEquals(i+0.1, a[i]);
+  }
+})();
diff --git a/test/mjsunit/array-push7.js b/test/mjsunit/array-push7.js
deleted file mode 100644
index 68c3a2a..0000000
--- a/test/mjsunit/array-push7.js
+++ /dev/null
@@ -1,60 +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.
-
-// Flags: --harmony-object-observe
-// Flags: --allow-natives-syntax
-
-var v = 0;
-
-function push_wrapper(array, value) {
-  array.push(value);
-}
-function pop_wrapper(array) {
-  return array.pop();
-}
-
-// Test that Object.observe() notification events are properly sent from
-// Array.push() and Array.pop() both from optimized and un-optimized code.
-var array = [];
-
-function somethingChanged(changes) {
-  v++;
-}
-
-Object.observe(array, somethingChanged);
-push_wrapper(array, 1);
-%RunMicrotasks();
-assertEquals(1, array.length);
-assertEquals(1, v);
-push_wrapper(array, 1);
-%RunMicrotasks();
-assertEquals(2, array.length);
-assertEquals(2, v);
-%OptimizeFunctionOnNextCall(push_wrapper);
-push_wrapper(array, 1);
-%RunMicrotasks();
-assertEquals(3, array.length);
-assertEquals(3, v);
-push_wrapper(array, 1);
-%RunMicrotasks();
-assertEquals(4, array.length);
-assertEquals(4, v);
-
-pop_wrapper(array);
-%RunMicrotasks();
-assertEquals(3, array.length);
-assertEquals(5, v);
-pop_wrapper(array);
-%RunMicrotasks();
-assertEquals(2, array.length);
-assertEquals(6, v);
-%OptimizeFunctionOnNextCall(pop_wrapper);
-pop_wrapper(array);
-%RunMicrotasks();
-assertEquals(1, array.length);
-assertEquals(7, v);
-pop_wrapper(array);
-%RunMicrotasks();
-assertEquals(0, array.length);
-assertEquals(8, v);
diff --git a/test/mjsunit/array-slice.js b/test/mjsunit/array-slice.js
index ae0e3bc..b017dd5 100644
--- a/test/mjsunit/array-slice.js
+++ b/test/mjsunit/array-slice.js
@@ -228,6 +228,7 @@
   func([]);
   func(['a'], 'a');
   func(['a', 1], 'a', 1);
+  func(['a', 1, 2, 3, 4, 5], 'a', 1, 2, 3, 4, 5);
   func(['a', 1, undefined], 'a', 1, undefined);
   func(['a', 1, undefined, void(0)], 'a', 1, undefined, void(0));
 })();
diff --git a/test/mjsunit/array-splice.js b/test/mjsunit/array-splice.js
index 744e954..75ff2d1 100644
--- a/test/mjsunit/array-splice.js
+++ b/test/mjsunit/array-splice.js
@@ -300,6 +300,55 @@
   }
 })();
 
+// Check the behaviour when approaching maximal values for length.
+(function() {
+  for (var i = 0; i < 7; i++) {
+    try {
+      new Array(Math.pow(2, 32) - 3).splice(-1, 0, 1, 2, 3, 4, 5);
+      throw 'Should have thrown RangeError';
+    } catch (e) {
+      assertTrue(e instanceof RangeError);
+    }
+
+    // Check smi boundary
+    var bigNum = (1 << 30) - 3;
+    var array = new Array(bigNum);
+    array.splice(-1, 0, 1, 2, 3, 4, 5, 6, 7);
+    assertEquals(bigNum + 7, array.length);
+  }
+})();
+
+(function() {
+  for (var i = 0; i < 7; i++) {
+    var a = [7, 8, 9];
+    a.splice(0, 0, 1, 2, 3, 4, 5, 6);
+    assertEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], a);
+    assertFalse(a.hasOwnProperty(10), "a.hasOwnProperty(10)");
+    assertEquals(undefined, a[10]);
+  }
+})();
+
+(function testSpliceDeleteDouble() {
+  var a = [1.1, 1.2, 1.3, 1.4];
+  a.splice(2, 1)
+  assertEquals([1.1, 1.2, 1.4], a);
+})();
+
+// Past this point the ArrayProtector is invalidated since we modify the
+// Array.prototype.
+
+// Check the case of JS builtin .splice()
+(function() {
+  for (var i = 0; i < 7; i++) {
+    var array = [1, 2, 3, 4];
+    Array.prototype[3] = 'foo';  // To force JS builtin.
+
+    var spliced = array.splice();
+
+    assertEquals([], spliced);
+    assertEquals([1, 2, 3, 4], array);
+  }
+})();
 
 // Now check the case with array of holes and some elements on prototype.
 (function() {
@@ -350,7 +399,6 @@
   }
 })();
 
-
 // Now check the case with array of holes and some elements on prototype.
 (function() {
   var len = 9;
@@ -397,46 +445,3 @@
                 "array.hasOwnProperty(Math.pow(2, 32) - 2)");
   }
 })();
-
-
-// Check the case of JS builtin .splice()
-(function() {
-  for (var i = 0; i < 7; i++) {
-    var array = [1, 2, 3, 4];
-    Array.prototype[3] = 'foo';  // To force JS builtin.
-
-    var spliced = array.splice();
-
-    assertEquals([], spliced);
-    assertEquals([1, 2, 3, 4], array);
-  }
-})();
-
-
-// Check the behaviour when approaching maximal values for length.
-(function() {
-  for (var i = 0; i < 7; i++) {
-    try {
-      new Array(Math.pow(2, 32) - 3).splice(-1, 0, 1, 2, 3, 4, 5);
-      throw 'Should have thrown RangeError';
-    } catch (e) {
-      assertTrue(e instanceof RangeError);
-    }
-
-    // Check smi boundary
-    var bigNum = (1 << 30) - 3;
-    var array = new Array(bigNum);
-    array.splice(-1, 0, 1, 2, 3, 4, 5, 6, 7);
-    assertEquals(bigNum + 7, array.length);
-  }
-})();
-
-(function() {
-  for (var i = 0; i < 7; i++) {
-    var a = [7, 8, 9];
-    a.splice(0, 0, 1, 2, 3, 4, 5, 6);
-    assertEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], a);
-    assertFalse(a.hasOwnProperty(10), "a.hasOwnProperty(10)");
-    assertEquals(undefined, a[10]);
-  }
-})();
diff --git a/test/mjsunit/compiler/escape-analysis-1.js b/test/mjsunit/compiler/escape-analysis-1.js
index b8c6644..f05040b 100644
--- a/test/mjsunit/compiler/escape-analysis-1.js
+++ b/test/mjsunit/compiler/escape-analysis-1.js
@@ -26,7 +26,6 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // Flags: --allow-natives-syntax --turbo-escape
-//
 
 function f(a) {
   "use strict";
diff --git a/test/mjsunit/compiler/escape-analysis-10.js b/test/mjsunit/compiler/escape-analysis-10.js
index c53cf4d..4f06d57 100644
--- a/test/mjsunit/compiler/escape-analysis-10.js
+++ b/test/mjsunit/compiler/escape-analysis-10.js
@@ -26,6 +26,7 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // Flags: --allow-natives-syntax --turbo-escape
+
 (function() {
   "use strict";
   function f() {
diff --git a/test/mjsunit/compiler/escape-analysis-2.js b/test/mjsunit/compiler/escape-analysis-2.js
index d116e9a..49f440e 100644
--- a/test/mjsunit/compiler/escape-analysis-2.js
+++ b/test/mjsunit/compiler/escape-analysis-2.js
@@ -26,7 +26,6 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // Flags: --allow-natives-syntax --turbo-escape
-//
 
 function f(a) {
   "use strict";
diff --git a/test/mjsunit/compiler/escape-analysis-3.js b/test/mjsunit/compiler/escape-analysis-3.js
index d1ebc9b..b92d1c3 100644
--- a/test/mjsunit/compiler/escape-analysis-3.js
+++ b/test/mjsunit/compiler/escape-analysis-3.js
@@ -26,7 +26,6 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // Flags: --allow-natives-syntax --turbo-escape
-//
 
 function f(a) {
   "use strict";
diff --git a/test/mjsunit/compiler/escape-analysis-4.js b/test/mjsunit/compiler/escape-analysis-4.js
index d9fdccc..ef9f95f 100644
--- a/test/mjsunit/compiler/escape-analysis-4.js
+++ b/test/mjsunit/compiler/escape-analysis-4.js
@@ -26,7 +26,6 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // Flags: --allow-natives-syntax --turbo-escape
-//
 
 function f(a) {
   "use strict";
diff --git a/test/mjsunit/compiler/escape-analysis-5.js b/test/mjsunit/compiler/escape-analysis-5.js
index cfaf81d..54b5e82 100644
--- a/test/mjsunit/compiler/escape-analysis-5.js
+++ b/test/mjsunit/compiler/escape-analysis-5.js
@@ -26,7 +26,6 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // Flags: --allow-natives-syntax --turbo-escape
-//
 
 function f(h) {
   "use strict";
diff --git a/test/mjsunit/compiler/escape-analysis-6.js b/test/mjsunit/compiler/escape-analysis-6.js
index 6143cfb..c36e7d9 100644
--- a/test/mjsunit/compiler/escape-analysis-6.js
+++ b/test/mjsunit/compiler/escape-analysis-6.js
@@ -26,7 +26,6 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // Flags: --allow-natives-syntax --turbo-escape
-//
 
 function f(a) {
   "use strict";
diff --git a/test/mjsunit/compiler/escape-analysis-7.js b/test/mjsunit/compiler/escape-analysis-7.js
index 16bc71c..cfa30cb 100644
--- a/test/mjsunit/compiler/escape-analysis-7.js
+++ b/test/mjsunit/compiler/escape-analysis-7.js
@@ -26,7 +26,6 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // Flags: --allow-natives-syntax --turbo-escape
-//
 
 function f() {
   this.x=0;
diff --git a/test/mjsunit/compiler/escape-analysis-8.js b/test/mjsunit/compiler/escape-analysis-8.js
index bc5b1d9..d9c6d25 100644
--- a/test/mjsunit/compiler/escape-analysis-8.js
+++ b/test/mjsunit/compiler/escape-analysis-8.js
@@ -26,7 +26,6 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // Flags: --allow-natives-syntax --turbo-escape
-//
 
 function f(a) {
   this.x=a;
diff --git a/test/mjsunit/compiler/escape-analysis-9.js b/test/mjsunit/compiler/escape-analysis-9.js
index a19786b..0b8f75c 100644
--- a/test/mjsunit/compiler/escape-analysis-9.js
+++ b/test/mjsunit/compiler/escape-analysis-9.js
@@ -26,7 +26,6 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // Flags: --allow-natives-syntax --turbo-escape
-//
 
 function f() {
   return arguments;
diff --git a/test/mjsunit/compiler/optimized-float32array-length.js b/test/mjsunit/compiler/optimized-float32array-length.js
new file mode 100644
index 0000000..eed8922
--- /dev/null
+++ b/test/mjsunit/compiler/optimized-float32array-length.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: --allow-natives-syntax
+
+var a = new Float32Array(1);
+function len(a) { return a.length; }
+assertEquals(1, len(a));
+assertEquals(1, len(a));
+%OptimizeFunctionOnNextCall(len);
+assertEquals(1, len(a));
+assertOptimized(len);
diff --git a/test/mjsunit/compiler/optimized-float64array-length.js b/test/mjsunit/compiler/optimized-float64array-length.js
new file mode 100644
index 0000000..f6a3d77
--- /dev/null
+++ b/test/mjsunit/compiler/optimized-float64array-length.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: --allow-natives-syntax
+
+var a = new Float64Array(1);
+function len(a) { return a.length; }
+assertEquals(1, len(a));
+assertEquals(1, len(a));
+%OptimizeFunctionOnNextCall(len);
+assertEquals(1, len(a));
+assertOptimized(len);
diff --git a/test/mjsunit/compiler/optimized-instanceof-1.js b/test/mjsunit/compiler/optimized-instanceof-1.js
new file mode 100644
index 0000000..538b0ef
--- /dev/null
+++ b/test/mjsunit/compiler/optimized-instanceof-1.js
@@ -0,0 +1,17 @@
+// 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: --allow-natives-syntax --harmony-instanceof
+
+function F() {}
+var f = new F
+
+var proto = Object.getPrototypeOf(F);
+Object.setPrototypeOf(F, null);
+F[Symbol.hasInstance] = function(v) { return true };
+Object.setPrototypeOf(F, proto);
+
+function foo(x) { return x instanceof F };
+%OptimizeFunctionOnNextCall(foo);
+assertTrue(foo(1));
diff --git a/test/mjsunit/compiler/optimized-instanceof-2.js b/test/mjsunit/compiler/optimized-instanceof-2.js
new file mode 100644
index 0000000..80bbdcd
--- /dev/null
+++ b/test/mjsunit/compiler/optimized-instanceof-2.js
@@ -0,0 +1,19 @@
+// 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: --allow-natives-syntax --harmony-instanceof
+
+function F() {}
+var f = new F
+
+function foo(x) { return x instanceof F };
+%OptimizeFunctionOnNextCall(foo);
+assertFalse(foo(1));
+
+var proto = Object.getPrototypeOf(F);
+Object.setPrototypeOf(F, null);
+F[Symbol.hasInstance] = function(v) { return true };
+Object.setPrototypeOf(F, proto);
+
+assertTrue(foo(1));
diff --git a/test/mjsunit/compiler/optimized-int32array-length.js b/test/mjsunit/compiler/optimized-int32array-length.js
new file mode 100644
index 0000000..250d523
--- /dev/null
+++ b/test/mjsunit/compiler/optimized-int32array-length.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: --allow-natives-syntax
+
+var a = new Int32Array(1);
+function len(a) { return a.length; }
+assertEquals(1, len(a));
+assertEquals(1, len(a));
+%OptimizeFunctionOnNextCall(len);
+assertEquals(1, len(a));
+assertOptimized(len);
diff --git a/test/mjsunit/compiler/optimized-uint32array-length.js b/test/mjsunit/compiler/optimized-uint32array-length.js
new file mode 100644
index 0000000..d389370
--- /dev/null
+++ b/test/mjsunit/compiler/optimized-uint32array-length.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: --allow-natives-syntax
+
+var a = new Uint32Array(1);
+function len(a) { return a.length; }
+assertEquals(1, len(a));
+assertEquals(1, len(a));
+%OptimizeFunctionOnNextCall(len);
+assertEquals(1, len(a));
+assertOptimized(len);
diff --git a/test/mjsunit/compiler/osr-alignment.js b/test/mjsunit/compiler/osr-alignment.js
index 085d6c4..f815e71 100644
--- a/test/mjsunit/compiler/osr-alignment.js
+++ b/test/mjsunit/compiler/osr-alignment.js
@@ -25,7 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Flags: --allow-natives-syntax --use-osr --turbo-osr
+// Flags: --allow-natives-syntax --use-osr
 
 function f1() {
   var sum = 0;
diff --git a/test/mjsunit/compiler/osr-backedges1.js b/test/mjsunit/compiler/osr-backedges1.js
index d415f4a..18a7e04 100644
--- a/test/mjsunit/compiler/osr-backedges1.js
+++ b/test/mjsunit/compiler/osr-backedges1.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: --allow-natives-syntax --use-osr --turbo-osr
+// Flags: --allow-natives-syntax --use-osr
 
 function foo(a) {
   var i = a | 0;
diff --git a/test/mjsunit/compiler/osr-block-scope-func.js b/test/mjsunit/compiler/osr-block-scope-func.js
index df4076c..7c41f54 100644
--- a/test/mjsunit/compiler/osr-block-scope-func.js
+++ b/test/mjsunit/compiler/osr-block-scope-func.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: --allow-natives-syntax --use-osr --turbo-osr
+// Flags: --allow-natives-syntax --use-osr
 
 "use strict";
 
diff --git a/test/mjsunit/compiler/osr-block-scope-id.js b/test/mjsunit/compiler/osr-block-scope-id.js
index 923c72f..bcc7cdd 100644
--- a/test/mjsunit/compiler/osr-block-scope-id.js
+++ b/test/mjsunit/compiler/osr-block-scope-id.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: --allow-natives-syntax --use-osr --turbo-osr
+// Flags: --allow-natives-syntax --use-osr
 
 "use strict";
 
diff --git a/test/mjsunit/compiler/osr-block-scope.js b/test/mjsunit/compiler/osr-block-scope.js
index 0d78cdc..c60f8af 100644
--- a/test/mjsunit/compiler/osr-block-scope.js
+++ b/test/mjsunit/compiler/osr-block-scope.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: --allow-natives-syntax --use-osr --turbo-osr
+// Flags: --allow-natives-syntax --use-osr
 
 "use strict";
 
diff --git a/test/mjsunit/compiler/osr-follow.js b/test/mjsunit/compiler/osr-follow.js
index b6a2e8e..46581a8 100644
--- a/test/mjsunit/compiler/osr-follow.js
+++ b/test/mjsunit/compiler/osr-follow.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: --use-osr --turbo-osr
+// Flags: --use-osr
 
 function foo(a) {
   var sum = 0;
diff --git a/test/mjsunit/compiler/osr-for-let.js b/test/mjsunit/compiler/osr-for-let.js
index 4b2fa3e..b8cef78 100644
--- a/test/mjsunit/compiler/osr-for-let.js
+++ b/test/mjsunit/compiler/osr-for-let.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: --allow-natives-syntax --use-osr --turbo-osr
+// Flags: --allow-natives-syntax --use-osr
 
 "use strict";
 
diff --git a/test/mjsunit/compiler/osr-forin-nested.js b/test/mjsunit/compiler/osr-forin-nested.js
index ad55b30..dd81089 100644
--- a/test/mjsunit/compiler/osr-forin-nested.js
+++ b/test/mjsunit/compiler/osr-forin-nested.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: --turbo-osr --allow-natives-syntax
+// Flags: --allow-natives-syntax
 
 function test(e, f, v) {
   assertEquals(e, f(v));
diff --git a/test/mjsunit/compiler/osr-forin.js b/test/mjsunit/compiler/osr-forin.js
index 8d16782..b45d200 100644
--- a/test/mjsunit/compiler/osr-forin.js
+++ b/test/mjsunit/compiler/osr-forin.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: --use-osr --turbo-osr
+// Flags: --use-osr
 
 function f(a) {
   var sum = 0;
diff --git a/test/mjsunit/compiler/osr-forof.js b/test/mjsunit/compiler/osr-forof.js
index 36bff09..ce7b24d 100644
--- a/test/mjsunit/compiler/osr-forof.js
+++ b/test/mjsunit/compiler/osr-forof.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: --use-osr --turbo-osr
+// Flags: --use-osr
 
 function f(a) {
   var sum = 0;
diff --git a/test/mjsunit/compiler/osr-function-id.js b/test/mjsunit/compiler/osr-function-id.js
index c506ae8..8761e85 100644
--- a/test/mjsunit/compiler/osr-function-id.js
+++ b/test/mjsunit/compiler/osr-function-id.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: --use-osr --turbo-osr
+// Flags: --use-osr
 
 function id(f) { return f; }
 
diff --git a/test/mjsunit/compiler/osr-function-id2.js b/test/mjsunit/compiler/osr-function-id2.js
index 561c62e..e25ec31 100644
--- a/test/mjsunit/compiler/osr-function-id2.js
+++ b/test/mjsunit/compiler/osr-function-id2.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: --use-osr --turbo-osr
+// Flags: --use-osr
 
 function id(f) { return f; }
 
diff --git a/test/mjsunit/compiler/osr-function.js b/test/mjsunit/compiler/osr-function.js
index 06d137b..cee7e9d 100644
--- a/test/mjsunit/compiler/osr-function.js
+++ b/test/mjsunit/compiler/osr-function.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: --use-osr --turbo-osr
+// Flags: --use-osr
 
 function foo() {
   var sum = 0;
diff --git a/test/mjsunit/compiler/osr-infinite.js b/test/mjsunit/compiler/osr-infinite.js
index aa74c87..9d0bb47 100644
--- a/test/mjsunit/compiler/osr-infinite.js
+++ b/test/mjsunit/compiler/osr-infinite.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: --use-osr --allow-natives-syntax --turbo-osr
+// Flags: --use-osr --allow-natives-syntax
 
 var global_counter = 0;
 
diff --git a/test/mjsunit/compiler/osr-labeled.js b/test/mjsunit/compiler/osr-labeled.js
index 1a97092..1384e9a 100644
--- a/test/mjsunit/compiler/osr-labeled.js
+++ b/test/mjsunit/compiler/osr-labeled.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: --allow-natives-syntax --use-osr --turbo-osr
+// Flags: --allow-natives-syntax --use-osr
 
 function foo() {
   var sum = 0;
diff --git a/test/mjsunit/compiler/osr-literals-adapted.js b/test/mjsunit/compiler/osr-literals-adapted.js
index 950d8b0..4d1798c 100644
--- a/test/mjsunit/compiler/osr-literals-adapted.js
+++ b/test/mjsunit/compiler/osr-literals-adapted.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: --allow-natives-syntax --use-osr --turbo-osr
+// Flags: --allow-natives-syntax --use-osr
 
 function mod() {
   function f0() {
diff --git a/test/mjsunit/compiler/osr-literals.js b/test/mjsunit/compiler/osr-literals.js
index d9f68a0..f2051dc 100644
--- a/test/mjsunit/compiler/osr-literals.js
+++ b/test/mjsunit/compiler/osr-literals.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: --allow-natives-syntax --use-osr --turbo-osr
+// Flags: --allow-natives-syntax --use-osr
 
 function mod() {
   function f0() {
diff --git a/test/mjsunit/compiler/osr-manual1.js b/test/mjsunit/compiler/osr-manual1.js
index 29a4948..c3db796 100644
--- a/test/mjsunit/compiler/osr-manual1.js
+++ b/test/mjsunit/compiler/osr-manual1.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: --allow-natives-syntax --use-osr --turbo-osr
+// Flags: --allow-natives-syntax --use-osr
 
 var counter = 111;
 
diff --git a/test/mjsunit/compiler/osr-manual2.js b/test/mjsunit/compiler/osr-manual2.js
index 8aa5d69..de7ec24 100644
--- a/test/mjsunit/compiler/osr-manual2.js
+++ b/test/mjsunit/compiler/osr-manual2.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: --allow-natives-syntax --use-osr --turbo-osr
+// Flags: --allow-natives-syntax --use-osr
 
 var counter = 188;
 
diff --git a/test/mjsunit/compiler/osr-multiple.js b/test/mjsunit/compiler/osr-multiple.js
index c318645..72fff85 100644
--- a/test/mjsunit/compiler/osr-multiple.js
+++ b/test/mjsunit/compiler/osr-multiple.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: --use-osr --turbo-osr
+// Flags: --use-osr
 
 function f1(a,b,c) {
   var x = 0;
diff --git a/test/mjsunit/compiler/osr-multiple2.js b/test/mjsunit/compiler/osr-multiple2.js
index 9a81bfb..edb627a 100644
--- a/test/mjsunit/compiler/osr-multiple2.js
+++ b/test/mjsunit/compiler/osr-multiple2.js
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 // Flags: --use-osr
-// TODO(titzer): enable --turbo-osr when nested OSR works.
 
 function f1(a,b,c) {
   var x = 0;
diff --git a/test/mjsunit/compiler/osr-multiple3.js b/test/mjsunit/compiler/osr-multiple3.js
index 0fb1ac7..fa703ea 100644
--- a/test/mjsunit/compiler/osr-multiple3.js
+++ b/test/mjsunit/compiler/osr-multiple3.js
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 // Flags: --use-osr
-// TODO(titzer): enable --turbo-osr when nested OSR works.
 
 function f1(a,b,c) {
   var x = 0;
diff --git a/test/mjsunit/compiler/osr-nested2.js b/test/mjsunit/compiler/osr-nested2.js
index 41bd9b2..efe31f1 100644
--- a/test/mjsunit/compiler/osr-nested2.js
+++ b/test/mjsunit/compiler/osr-nested2.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: --allow-natives-syntax --use-osr --turbo-osr
+// Flags: --allow-natives-syntax --use-osr
 
 function f() {
   var sum = 0;
diff --git a/test/mjsunit/compiler/osr-nested2b.js b/test/mjsunit/compiler/osr-nested2b.js
index e64c10c..1808811 100644
--- a/test/mjsunit/compiler/osr-nested2b.js
+++ b/test/mjsunit/compiler/osr-nested2b.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: --allow-natives-syntax --use-osr --turbo-osr
+// Flags: --allow-natives-syntax --use-osr
 
 function f() {
   var sum = 0;
diff --git a/test/mjsunit/compiler/osr-nested3.js b/test/mjsunit/compiler/osr-nested3.js
index f5d09ba..d7c144b 100644
--- a/test/mjsunit/compiler/osr-nested3.js
+++ b/test/mjsunit/compiler/osr-nested3.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: --allow-natives-syntax --use-osr --turbo-osr
+// Flags: --allow-natives-syntax --use-osr
 
 function f() {
   var sum = 0;
diff --git a/test/mjsunit/compiler/osr-nested3b.js b/test/mjsunit/compiler/osr-nested3b.js
index 32ac2a7..a10d328 100644
--- a/test/mjsunit/compiler/osr-nested3b.js
+++ b/test/mjsunit/compiler/osr-nested3b.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: --allow-natives-syntax --use-osr --turbo-osr
+// Flags: --allow-natives-syntax --use-osr
 
 function f() {
   var sum = 0;
diff --git a/test/mjsunit/compiler/osr-regex-id.js b/test/mjsunit/compiler/osr-regex-id.js
index 7831b14..e0b4dad 100644
--- a/test/mjsunit/compiler/osr-regex-id.js
+++ b/test/mjsunit/compiler/osr-regex-id.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: --allow-natives-syntax --use-osr --turbo-osr
+// Flags: --allow-natives-syntax --use-osr
 
 function id(f) { return f; }
 
diff --git a/test/mjsunit/compiler/osr-sar.js b/test/mjsunit/compiler/osr-sar.js
index cc04adc..02684f0 100644
--- a/test/mjsunit/compiler/osr-sar.js
+++ b/test/mjsunit/compiler/osr-sar.js
@@ -25,7 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Flags: --allow-natives-syntax --use-osr --turbo-osr
+// Flags: --allow-natives-syntax --use-osr
 
 function test() {
   // Loop to force OSR.
diff --git a/test/mjsunit/compiler/osr-warm.js b/test/mjsunit/compiler/osr-warm.js
index 7c30c07..73e1fd5 100644
--- a/test/mjsunit/compiler/osr-warm.js
+++ b/test/mjsunit/compiler/osr-warm.js
@@ -25,7 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Flags: --use-osr --turbo-osr
+// Flags: --use-osr
 
 function f1(x) {
   while (x > 0) {
diff --git a/test/mjsunit/compiler/osr-while-let.js b/test/mjsunit/compiler/osr-while-let.js
index c19cf6c..11ebc4b 100644
--- a/test/mjsunit/compiler/osr-while-let.js
+++ b/test/mjsunit/compiler/osr-while-let.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: --allow-natives-syntax --use-osr --turbo-osr
+// Flags: --allow-natives-syntax --use-osr
 
 "use strict";
 
diff --git a/test/mjsunit/compiler/regress-607493.js b/test/mjsunit/compiler/regress-607493.js
new file mode 100644
index 0000000..540b47e
--- /dev/null
+++ b/test/mjsunit/compiler/regress-607493.js
@@ -0,0 +1,37 @@
+// 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: --allow-natives-syntax
+
+(function ForInTryCatchContrinueOsr() {
+  var a = [1];
+
+  function g() {
+    for (var x in a) {
+      try {
+        for (var i = 0; i < 10; i++) { %OptimizeOsr(); }
+        return;
+      } catch(e) {
+        continue;
+      }
+    }
+  }
+
+  g();
+})();
+
+(function ForInContinueNestedOsr() {
+  var a = [1];
+
+  function g() {
+    for (var x in a) {
+      if (x) {
+        for (var i = 0; i < 10; i++) { %OptimizeOsr(); }
+      }
+      continue;
+    }
+  }
+
+  g();
+})();
diff --git a/test/mjsunit/compiler/regress-621147.js b/test/mjsunit/compiler/regress-621147.js
new file mode 100644
index 0000000..0a5a221
--- /dev/null
+++ b/test/mjsunit/compiler/regress-621147.js
@@ -0,0 +1,29 @@
+// 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.
+
+// Flags: --allow-natives-syntax --turbo-filter=test2
+
+function test(n) {
+  return Array(n);
+}
+
+function test2() {
+  return test(2);
+}
+
+function test3(a) {
+  a[0] = 1;
+}
+
+test(0);
+
+var smi_array = [1,2];
+smi_array[2] = 3;
+test3(smi_array);
+
+%OptimizeFunctionOnNextCall(test2);
+
+var broken_array = test2();
+test3(broken_array);
+1+broken_array[0];
diff --git a/test/mjsunit/compiler/try-osr.js b/test/mjsunit/compiler/try-osr.js
index e4eb8dd..c0ef27a 100644
--- a/test/mjsunit/compiler/try-osr.js
+++ b/test/mjsunit/compiler/try-osr.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: --allow-natives-syntax --turbo-osr
+// Flags: --allow-natives-syntax
 
 function OSRInsideTry(x) {
   try {
diff --git a/test/mjsunit/debug-allscopes-on-debugger.js b/test/mjsunit/debug-allscopes-on-debugger.js
index b7a8dff..17668cf 100644
--- a/test/mjsunit/debug-allscopes-on-debugger.js
+++ b/test/mjsunit/debug-allscopes-on-debugger.js
@@ -49,10 +49,11 @@
   var i = 0; // Break 1.
   i++; // Break 2.
   i++; // Break 3.
-  return i; // Break 4.
-}()); // Break 5.
+  debugger;  // Break 4.
+  return i; // Break 5.
+}()); // Break 6.
 
-assertNull(exception); // Break 6.
+assertNull(exception); // Break 7.
 assertEquals(expected_breaks, break_count);
 
 Debug.setListener(null);
diff --git a/test/mjsunit/debug-backtrace-text.js b/test/mjsunit/debug-backtrace-text.js
index 61648fa..cfc89e6 100644
--- a/test/mjsunit/debug-backtrace-text.js
+++ b/test/mjsunit/debug-backtrace-text.js
@@ -35,7 +35,8 @@
 
 Point.prototype.distanceTo = function(p) {
   debugger;
-  return Math.sqrt(Math.pow(Math.abs(this.x - p.x), 2) + Math.pow(Math.abs(this.y - p.y), 2))
+  return Math.sqrt(Math.pow(Math.abs(this.x - p.x), 2) +
+         Math.pow(Math.abs(this.y - p.y), 2))
 }
 
 p1 = new Point(1,1);
@@ -58,7 +59,7 @@
 // Get the Debug object exposed from the debug context global object.
 Debug = debug.Debug
 
-testConstructor = false;  // Flag to control which part of the test is run.
+what = 'constructor';  // Flag to control which part of the test is run.
 listenerCalled = false;
 exception = false;
 
@@ -72,30 +73,47 @@
 
 function listener(event, exec_state, event_data, data) {
   try {
-  if (event == Debug.DebugEvent.Break)
-  {
-    if (!testConstructor) {
-      // The expected backtrace is
-      // 0: Call distance on Point where distance is a property on the prototype
-      // 1: Call distance on Point where distance is a direct property
-      // 2: Call on function an array element 2
-      // 3: [anonymous]
-      assertEquals("#<Point>.distanceTo(p=#<Point>)", exec_state.frame(0).invocationText());
-      assertEquals("#<Point>.distanceTo(p=#<Point>)", exec_state.frame(1).invocationText());
-      assertEquals("#<Array>[2](aka distance)(p=#<Point>, q=#<Point>)", exec_state.frame(2).invocationText());
-      assertEquals("[anonymous]()", exec_state.frame(3).invocationText());
-      listenerCalled = true;
-    } else {
-      // The expected backtrace is
-      // 0: Call Point constructor
-      // 1: Call on global function createPoint
-      // 2: [anonymous]
-      assertEquals("new Point(x=0, y=0)", exec_state.frame(0).invocationText());
-      assertEquals("createPoint(x=0, y=0)", exec_state.frame(1).invocationText());
-      assertEquals("[anonymous]()", exec_state.frame(2).invocationText());
-      listenerCalled = true;
+    if (event == Debug.DebugEvent.Break) {
+      if (what == 'constructor') {
+        // The expected backtrace is
+        // 0: Call distance on Point where distance is a prototype property
+        // 1: Call distance on Point where distance is a direct property
+        // 2: Call on function an array element 2
+        // 3: [anonymous]
+        assertEquals("#<Point>.distanceTo(p=#<Point>)",
+                     exec_state.frame(0).invocationText());
+        assertEquals("#<Point>.distanceTo(p=#<Point>)",
+                     exec_state.frame(1).invocationText());
+        assertEquals("#<Array>[2](aka distance)(p=#<Point>, q=#<Point>)",
+                     exec_state.frame(2).invocationText());
+        assertEquals("[anonymous]()", exec_state.frame(3).invocationText());
+        listenerCalled = true;
+      } else if (what == 'breakpoint') {
+        // The expected backtrace is
+        // 0: Call Point constructor
+        // 1: Call on global function createPoint
+        // 2: [anonymous]
+        assertEquals("new Point(x=0, y=0)",
+                     exec_state.frame(0).invocationText());
+        assertEquals("createPoint(x=0, y=0)",
+                     exec_state.frame(1).invocationText());
+        assertEquals("[anonymous]()", exec_state.frame(2).invocationText());
+        listenerCalled = true;
+      } else if (what == 'symbol') {
+        // The expected backtrace is
+        // 0: Call Point constructor
+        // 1: Call on symbol method
+        // 2: [anonymous]
+        assertEquals("new Point(x=0, y=0)",
+                     exec_state.frame(0).invocationText());
+        assertEquals("#<Object>[Symbol(Das Symbol)](x=0, y=0)",
+                     exec_state.frame(1).invocationText());
+        assertEquals("[anonymous]()", exec_state.frame(2).invocationText());
+        listenerCalled = true;
+      } else {
+        assertUnreachable();
+      }
     }
-  }
   } catch (e) {
     exception = e
   };
@@ -112,11 +130,21 @@
 assertFalse(exception, "exception in listener")
 
 // Set a break point and call to invoke the debug event listener.
+what = 'breakpoint';
 listenerCalled = false;
-testConstructor = true;
 Debug.setBreakPoint(Point, 0, 0);
 createPoint(0, 0);
 
 // Make sure that the debug event listener vas invoked (again).
 assertTrue(listenerCalled);
 assertFalse(exception, "exception in listener")
+
+what = 'symbol';
+listenerCalled = false;
+var S = Symbol('Das Symbol');
+var o = { [S](x, y) { return new Point(x, y); } };
+Debug.setBreakPoint(Point, 0, 0);
+o[S](0, 0);
+
+assertTrue(listenerCalled);
+assertFalse(exception, "exception in listener")
diff --git a/test/mjsunit/debug-eval-scope.js b/test/mjsunit/debug-eval-scope.js
new file mode 100644
index 0000000..2b97bf6
--- /dev/null
+++ b/test/mjsunit/debug-eval-scope.js
@@ -0,0 +1,144 @@
+// 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 --no-always-opt
+
+// Test that the (strict) eval scope is visible to the debugger.
+
+var Debug = debug.Debug;
+var exception = null;
+var delegate = null;
+
+function listener(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    delegate(exec_state);
+  } catch (e) {
+    exception = e;
+  }
+}
+
+Debug.setListener(listener);
+
+// Current function is the top-level eval.
+// We can access stack- and context-allocated values in the eval-scope.
+delegate = function(exec_state) {
+  assertEquals([ debug.ScopeType.Eval,
+                 debug.ScopeType.Script,
+                 debug.ScopeType.Global ],
+               exec_state.frame(0).allScopes().map(s => s.scopeType()));
+  var scope = exec_state.frame(0).scope(0);
+  assertEquals(1, scope.scopeObject().property("a").value().value());
+  assertEquals(1, exec_state.frame(0).evaluate("a").value());
+  scope.setVariableValue("a", 2);
+  assertEquals(2, exec_state.frame(0).evaluate("a++").value());
+}
+
+eval("'use strict';      \n" +
+     "var a = 1;         \n" +
+     "debugger;          \n" +
+     "assertEquals(3, a);\n");
+
+eval("'use strict';      \n" +
+     "var a = 1;         \n" +
+     "(x=>a);            \n" +  // Force context-allocation.
+     "debugger;          \n" +
+     "assertEquals(3, a);\n");
+
+// Current function is an inner function.
+// We cannot access stack-allocated values in the eval-scope.
+delegate = function(exec_state) {
+  assertEquals([ debug.ScopeType.Local,
+                 debug.ScopeType.Script,
+                 debug.ScopeType.Global ],
+               exec_state.frame(0).allScopes().map(s => s.scopeType()));
+  assertEquals([ debug.ScopeType.Eval,
+                 debug.ScopeType.Script,
+                 debug.ScopeType.Global ],
+               exec_state.frame(1).allScopes().map(s => s.scopeType()));
+  var scope = exec_state.frame(0).scope(0);
+  assertThrows(() => exec_state.frame(0).evaluate("a"), ReferenceError);
+  assertTrue(scope.scopeObject().property("a").isUndefined());
+}
+
+eval("'use strict';       \n" +
+     "var a = 1;          \n" +
+     "(() => {debugger})()\n");
+
+// Current function is an escaped inner function.
+delegate = function(exec_state) {
+  assertEquals([ debug.ScopeType.Local,
+                 debug.ScopeType.Script,
+                 debug.ScopeType.Global ],
+               exec_state.frame(0).allScopes().map(s => s.scopeType()));
+  assertEquals([ debug.ScopeType.Script,
+                 debug.ScopeType.Global ],
+               exec_state.frame(1).allScopes().map(s => s.scopeType()));
+  var scope = exec_state.frame(0).scope(0);
+  assertThrows(() => exec_state.frame(0).evaluate("a"), ReferenceError);
+  assertTrue(scope.scopeObject().property("a").isUndefined());
+}
+
+var f = eval("'use strict';   \n" +
+             "var a = 1;      \n" +
+             "() => {debugger}\n");
+f();
+
+// Current function is an inner function.
+// We can access context-allocated values in the eval-scope.
+delegate = function(exec_state) {
+  assertEquals([ debug.ScopeType.Local,
+                 debug.ScopeType.Closure,
+                 debug.ScopeType.Script,
+                 debug.ScopeType.Global ],
+               exec_state.frame(0).allScopes().map(s => s.scopeType()));
+  assertEquals([ debug.ScopeType.Eval,
+                 debug.ScopeType.Script,
+                 debug.ScopeType.Global ],
+               exec_state.frame(1).allScopes().map(s => s.scopeType()));
+  var scope = exec_state.frame(1).scope(0);
+  assertEquals(1, scope.scopeObject().property("a").value().value());
+  assertEquals(1, exec_state.frame(1).evaluate("a").value());
+  assertEquals(1, exec_state.frame(0).evaluate("a").value());
+  scope.setVariableValue("a", 2);
+  assertEquals(2, exec_state.frame(0).evaluate("a++").value());
+  assertEquals(3, exec_state.frame(1).evaluate("a++").value());
+}
+
+eval("'use strict';               \n" +
+     "var a = 1;                  \n" +
+     "(() => { a;                 \n" +  // Force context-allocation.
+     "         debugger;          \n" +
+     "         assertEquals(4, a);\n" +
+     "       })();                \n"
+     );
+
+// Current function is an escaped inner function.
+// We can access context-allocated values in the eval-scope.
+delegate = function(exec_state) {
+  assertEquals([ debug.ScopeType.Local,
+                 debug.ScopeType.Closure,
+                 debug.ScopeType.Script,
+                 debug.ScopeType.Global ],
+               exec_state.frame(0).allScopes().map(s => s.scopeType()));
+  assertEquals([ debug.ScopeType.Script,
+                 debug.ScopeType.Global ],
+               exec_state.frame(1).allScopes().map(s => s.scopeType()));
+  var scope = exec_state.frame(0).scope(1);
+  assertEquals(1, scope.scopeObject().property("a").value().value());
+  assertEquals(1, exec_state.frame(0).evaluate("a").value());
+  scope.setVariableValue("a", 2);
+  assertEquals(2, exec_state.frame(0).evaluate("a++").value());
+}
+
+var g = eval("'use strict';              \n" +
+             "var a = 1;                 \n" +
+             "() => { a;                 \n" +
+             "        debugger;          \n" +
+             "        assertEquals(3, a);\n" +
+             "      }                    \n");
+g();
+
+Debug.setListener(null);
+assertNull(exception);
diff --git a/test/mjsunit/debug-evaluate-nested.js b/test/mjsunit/debug-evaluate-nested.js
index da11b90..965b5a7 100644
--- a/test/mjsunit/debug-evaluate-nested.js
+++ b/test/mjsunit/debug-evaluate-nested.js
@@ -34,7 +34,7 @@
       exec_state.frame(0).evaluate("debugger;");
     } else {
       checkScopes(exec_state.frame(0).allScopes(),
-                  [ ScopeType.With, ScopeType.Closure,
+                  [ ScopeType.Eval, ScopeType.With, ScopeType.Closure,
                     ScopeType.Script, ScopeType.Global ]);
     }
   } catch (e) {
diff --git a/test/mjsunit/debug-function-scopes.js b/test/mjsunit/debug-function-scopes.js
index f63d7b2..5509038 100644
--- a/test/mjsunit/debug-function-scopes.js
+++ b/test/mjsunit/debug-function-scopes.js
@@ -42,14 +42,7 @@
   }
 }
 
-// A copy of the scope types from debug/mirrors.js.
-var ScopeType = { Global: 0,
-                  Local: 1,
-                  With: 2,
-                  Closure: 3,
-                  Catch: 4,
-                  Block: 5,
-                  Script: 6};
+var ScopeType = debug.ScopeType;
 
 var f1 = (function F1(x) {
   function F2(y) {
diff --git a/test/mjsunit/debug-liveedit-exceptions.js b/test/mjsunit/debug-liveedit-exceptions.js
new file mode 100644
index 0000000..28ec01d
--- /dev/null
+++ b/test/mjsunit/debug-liveedit-exceptions.js
@@ -0,0 +1,67 @@
+// 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
+
+Debug = debug.Debug
+
+function BestEditor() {
+  throw 'Emacs';
+}
+
+var exception = null;
+var results = [];
+var log = []
+
+function listener(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.Exception) return;
+  try {
+    var source_line = event_data.sourceLineText();
+    print(source_line);
+    log.push(source_line);
+    switch (results.length) {
+      case 0:
+        Replace(BestEditor, "Emacs", "Eclipse");
+        break;
+      case 1:
+        Replace(BestEditor, "Eclipse", "Vim");
+        break;
+      case 2:
+        break;
+      default:
+        assertUnreachable();
+    }
+  } catch (e) {
+    exception = e;
+  }
+};
+
+function Replace(fun, original, patch) {
+  var script = Debug.findScript(fun);
+  if (fun.toString().indexOf(original) < 0) return;
+  var patch_pos = script.source.indexOf(original);
+  var change_log = [];
+  Debug.LiveEdit.TestApi.ApplySingleChunkPatch(script, patch_pos, original.length, patch, change_log);
+}
+
+Debug.setListener(listener);
+Debug.setBreakOnException();
+
+for (var i = 0; i < 3; i++) {
+  try {
+    BestEditor();
+  } catch (e) {
+    results.push(e);
+  }
+}
+Debug.setListener(null);
+
+assertNull(exception);
+assertEquals(["Emacs", "Eclipse", "Vim"], results);
+print(JSON.stringify(log, 1));
+assertEquals([
+  "  throw 'Emacs';",
+  "  throw 'Eclipse';",
+  "  throw 'Vim';",
+], log);
diff --git a/test/mjsunit/debug-liveedit-stepin.js b/test/mjsunit/debug-liveedit-stepin.js
index 601a66f..c6070ce 100644
--- a/test/mjsunit/debug-liveedit-stepin.js
+++ b/test/mjsunit/debug-liveedit-stepin.js
@@ -7,8 +7,7 @@
 Debug = debug.Debug
 
 function BestEditor() {
-  var best_editor = "Emacs";
-  return best_editor;
+  return 'Emacs';
 }
 
 var exception = null;
@@ -62,20 +61,15 @@
 assertEquals([
   "debugger;",
   "results.push(BestEditor());",
-  "  var best_editor = \"Emacs\";",
-  "  return best_editor;","}",
+  "  return 'Emacs';","}",
   "results.push(BestEditor());",
   "results.push(BestEditor());",
-  "  var best_editor = \"Emacs\";",
-  "  return best_editor;",
-  "  var best_editor = \"Eclipse\";",
-  "  return best_editor;","}",
+  "  return 'Emacs';",
+  "  return 'Eclipse';","}",
   "results.push(BestEditor());",
   "results.push(BestEditor());",
-  "  var best_editor = \"Eclipse\";",
-  "  return best_editor;",
-  "  var best_editor = \"Vim\";",
-  "  return best_editor;",
+  "  return 'Eclipse';",
+  "  return 'Vim';",
   "}","results.push(BestEditor());",
   "Debug.setListener(null);"
 ], log);
diff --git a/test/mjsunit/debug-scopes.js b/test/mjsunit/debug-scopes.js
index 3659d4e..935de9c 100644
--- a/test/mjsunit/debug-scopes.js
+++ b/test/mjsunit/debug-scopes.js
@@ -183,10 +183,8 @@
   if (!scope.scopeObject().property('this').isUndefined()) {
     scope_size--;
   }
-  // Skip property with empty name.
-  if (!scope.scopeObject().property('').isUndefined()) {
-    scope_size--;
-  }
+  // Temporary variables introduced by the parser have not been materialized.
+  assertTrue(scope.scopeObject().property('').isUndefined());
 
   if (count != scope_size) {
     print('Names found in scope:');
@@ -1179,11 +1177,10 @@
 
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Block,
-                   debug.ScopeType.Block,
                    debug.ScopeType.Local,
                    debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
-  CheckScopeChainPositions([{start: 52, end: 111}, {start: 42, end: 111}, {start: 22, end: 145}, {}, {}], exec_state);
+  CheckScopeChainPositions([{start: 52, end: 111}, {start: 22, end: 145}, {}, {}], exec_state);
 }
 eval(code3);
 EndTest();
diff --git a/test/mjsunit/debug-stack-check-position.js b/test/mjsunit/debug-stack-check-position.js
new file mode 100644
index 0000000..a5570ce
--- /dev/null
+++ b/test/mjsunit/debug-stack-check-position.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: --expose-debug-as debug --allow-natives-syntax
+
+var Debug = debug.Debug;
+var exception = null;
+var loop = true;
+
+function listener(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    assertTrue(exec_state.frame(0).sourceLineText().indexOf("BREAK") > 0);
+  } catch (e) {
+    exception = e;
+  }
+}
+
+function f() {     // BREAK
+  return 1;
+}
+
+Debug.setListener(listener);
+
+%ScheduleBreak();  // Break on function entry.
+f();
+
+Debug.setListener(null);
+assertNull(exception);
diff --git a/test/mjsunit/delete.js b/test/mjsunit/delete.js
index 8d4636a..20fa6bf 100644
--- a/test/mjsunit/delete.js
+++ b/test/mjsunit/delete.js
@@ -178,3 +178,17 @@
 }
 
 load_deleted_property_using_IC();
+
+
+(function deleteLargeDoubleArrayAtEnd() {
+  var o = {};
+  var max = 100000;
+  for (var i = 0; i <= max; i++) {
+    o[i] = 1.1;
+  }
+  delete o[max];
+  for (var i = 0; i < max; i++) {
+    assertEquals(1.1, o[i]);
+  }
+  assertEquals(undefined, o[max]);
+})();
diff --git a/test/mjsunit/es6/array-concat.js b/test/mjsunit/es6/array-concat.js
index fe320d6..00edfd6 100644
--- a/test/mjsunit/es6/array-concat.js
+++ b/test/mjsunit/es6/array-concat.js
@@ -1,7 +1,6 @@
 // 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.
-
 (function testArrayConcatArity() {
   "use strict";
   assertEquals(1, Array.prototype.concat.length);
@@ -20,6 +19,15 @@
   assertEquals(false, desc.enumerable);
 })();
 
+(function testNonConcatSpreadableArray() {
+  "use strict"
+  var array = [1, 2, 3];
+  assertEquals(array, [].concat(array));
+  assertEquals(array, array.concat([]));
+  array[Symbol.isConcatSpreadable] = false;
+  assertEquals([[1,2,3]], [].concat(array));
+  assertEquals([[1,2,3]], array.concat([]));
+})();
 
 (function testConcatArrayLike() {
   "use strict";
diff --git a/test/mjsunit/es6/array-species-neg-zero.js b/test/mjsunit/es6/array-species-neg-zero.js
new file mode 100644
index 0000000..d60b8ba
--- /dev/null
+++ b/test/mjsunit/es6/array-species-neg-zero.js
@@ -0,0 +1,23 @@
+// 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.
+
+/**
+ * 9.4.2.3 ArraySpeciesCreate(originalArray, length)
+ *
+ * 1. Assert: length is an integer Number ≥ 0.
+ * 2. If length is −0, let length be +0.
+ * [...]
+ */
+
+var x = [];
+var deleteCount;
+
+x.constructor = function() {};
+x.constructor[Symbol.species] = function(param) {
+  deleteCount = param;
+};
+
+x.splice(0, -0);
+
+assertEquals(0, deleteCount);
diff --git a/test/mjsunit/harmony/block-conflicts-sloppy.js b/test/mjsunit/es6/block-conflicts-sloppy.js
similarity index 98%
rename from test/mjsunit/harmony/block-conflicts-sloppy.js
rename to test/mjsunit/es6/block-conflicts-sloppy.js
index 8908ce4..866abee 100644
--- a/test/mjsunit/harmony/block-conflicts-sloppy.js
+++ b/test/mjsunit/es6/block-conflicts-sloppy.js
@@ -4,8 +4,6 @@
 
 // Test for conflicting variable bindings.
 
-// Flags: --harmony-sloppy --harmony-sloppy-let --harmony-sloppy-function
-
 function CheckException(e) {
   var string = e.toString();
   assertTrue(string.indexOf("has already been declared") >= 0 ||
diff --git a/test/mjsunit/harmony/block-const-assign-sloppy.js b/test/mjsunit/es6/block-const-assign-sloppy.js
similarity index 98%
rename from test/mjsunit/harmony/block-const-assign-sloppy.js
rename to test/mjsunit/es6/block-const-assign-sloppy.js
index 5dde82c..99024ef 100644
--- a/test/mjsunit/harmony/block-const-assign-sloppy.js
+++ b/test/mjsunit/es6/block-const-assign-sloppy.js
@@ -25,8 +25,6 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Flags: --harmony-sloppy --harmony-sloppy-let
-
 // Test that we throw early syntax errors in harmony mode
 // when using an immutable binding in an assigment or with
 // prefix/postfix decrement/increment operators.
diff --git a/test/mjsunit/es6/block-early-errors.js b/test/mjsunit/es6/block-early-errors.js
deleted file mode 100644
index 4af6521..0000000
--- a/test/mjsunit/es6/block-early-errors.js
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --no-harmony-sloppy-let
-
-function CheckException(e) {
-  var string = e.toString();
-  assertInstanceof(e, SyntaxError);
-}
-
-function Check(str) {
-  try {
-    eval("(function () { " + str + " })");
-    assertUnreachable();
-  } catch (e) {
-    CheckException(e);
-  }
-  try {
-    eval("(function () { { " + str + " } })");
-    assertUnreachable();
-  } catch (e) {
-    CheckException(e);
-  }
-}
-
-// Check for early syntax errors when using let
-// declarations outside of strict mode.
-Check("let x;");
-Check("let x = 1;");
-Check("let x, y;");
diff --git a/test/mjsunit/harmony/block-eval-var-over-let.js b/test/mjsunit/es6/block-eval-var-over-let.js
similarity index 96%
rename from test/mjsunit/harmony/block-eval-var-over-let.js
rename to test/mjsunit/es6/block-eval-var-over-let.js
index 98091b4..febc83f 100644
--- a/test/mjsunit/harmony/block-eval-var-over-let.js
+++ b/test/mjsunit/es6/block-eval-var-over-let.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-sloppy --harmony-sloppy-let --harmony-sloppy-function
-
 // Var-let conflict in a function throws, even if the var is in an eval
 
 // Throws at the top level of a function
diff --git a/test/mjsunit/harmony/block-for-sloppy.js b/test/mjsunit/es6/block-for-sloppy.js
similarity index 98%
rename from test/mjsunit/harmony/block-for-sloppy.js
rename to test/mjsunit/es6/block-for-sloppy.js
index 261c46a..4f0f63f 100644
--- a/test/mjsunit/harmony/block-for-sloppy.js
+++ b/test/mjsunit/es6/block-for-sloppy.js
@@ -25,8 +25,6 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Flags: --harmony-sloppy --harmony-sloppy-let
-
 function props(x) {
   var array = [];
   for (let p in x) array.push(p);
diff --git a/test/mjsunit/harmony/block-leave-sloppy.js b/test/mjsunit/es6/block-leave-sloppy.js
similarity index 98%
rename from test/mjsunit/harmony/block-leave-sloppy.js
rename to test/mjsunit/es6/block-leave-sloppy.js
index 0023fa0..1313026 100644
--- a/test/mjsunit/harmony/block-leave-sloppy.js
+++ b/test/mjsunit/es6/block-leave-sloppy.js
@@ -25,8 +25,6 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Flags: --harmony-sloppy --harmony-sloppy-let
-
 // We want to test the context chain shape.  In each of the tests cases
 // below, the outer with is to force a runtime lookup of the identifier 'x'
 // to actually verify that the inner context has been discarded.  A static
diff --git a/test/mjsunit/es6/block-let-contextual-sloppy.js b/test/mjsunit/es6/block-let-contextual-sloppy.js
index ac7bca1..8282d77 100644
--- a/test/mjsunit/es6/block-let-contextual-sloppy.js
+++ b/test/mjsunit/es6/block-let-contextual-sloppy.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-sloppy --harmony-sloppy-let
-
 // let is usable as a variable with var, but not let or ES6 const
 
 (function (){
diff --git a/test/mjsunit/harmony/block-let-crankshaft-sloppy.js b/test/mjsunit/es6/block-let-crankshaft-sloppy.js
similarity index 99%
rename from test/mjsunit/harmony/block-let-crankshaft-sloppy.js
rename to test/mjsunit/es6/block-let-crankshaft-sloppy.js
index 4f29c05..b5e81f7 100644
--- a/test/mjsunit/harmony/block-let-crankshaft-sloppy.js
+++ b/test/mjsunit/es6/block-let-crankshaft-sloppy.js
@@ -26,7 +26,6 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // Flags: --allow-natives-syntax
-// Flags: --harmony-sloppy --harmony-sloppy-let
 
 // Check that the following functions are optimizable.
 var functions = [ f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14,
diff --git a/test/mjsunit/harmony/block-let-declaration-sloppy.js b/test/mjsunit/es6/block-let-declaration-sloppy.js
similarity index 98%
rename from test/mjsunit/harmony/block-let-declaration-sloppy.js
rename to test/mjsunit/es6/block-let-declaration-sloppy.js
index af95553..ea0e39b 100644
--- a/test/mjsunit/harmony/block-let-declaration-sloppy.js
+++ b/test/mjsunit/es6/block-let-declaration-sloppy.js
@@ -27,8 +27,6 @@
 
 // Test let declarations in various settings.
 
-// Flags: --harmony-sloppy --harmony-sloppy-let
-
 // Global
 let x;
 let y = 2;
diff --git a/test/mjsunit/harmony/block-let-semantics-sloppy.js b/test/mjsunit/es6/block-let-semantics-sloppy.js
similarity index 98%
rename from test/mjsunit/harmony/block-let-semantics-sloppy.js
rename to test/mjsunit/es6/block-let-semantics-sloppy.js
index a55ff8f..4102ec8 100644
--- a/test/mjsunit/harmony/block-let-semantics-sloppy.js
+++ b/test/mjsunit/es6/block-let-semantics-sloppy.js
@@ -25,8 +25,6 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Flags: --harmony-sloppy --harmony-sloppy-let --harmony-sloppy-function
-
 // Test temporal dead zone semantics of let bound variables in
 // function and block scopes.
 
diff --git a/test/mjsunit/es6/block-non-strict-errors.js b/test/mjsunit/es6/block-non-strict-errors.js
deleted file mode 100644
index db7f558..0000000
--- a/test/mjsunit/es6/block-non-strict-errors.js
+++ /dev/null
@@ -1,42 +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.
-
-// Flags: --no-harmony-sloppy-let --no-harmony-sloppy-function
-// Flags: --no-harmony-sloppy
-
-function CheckError(source) {
-  var exception = null;
-  try {
-    eval(source);
-  } catch (e) {
-    exception = e;
-  }
-  assertNotNull(exception);
-  assertEquals(
-      "Block-scoped declarations (let, const, function, class) not yet supported outside strict mode",
-      exception.message);
-}
-
-
-function CheckOk(source) {
-  eval(source);
-}
-
-CheckError("let x = 1;");
-CheckError("{ let x = 1; }");
-CheckError("function f() { let x = 1; }");
-CheckError("for (let x = 1; x < 1; x++) {}");
-CheckError("for (let x of []) {}");
-CheckError("for (let x in []) {}");
-CheckError("class C {}");
-CheckError("class C extends Array {}");
-CheckError("(class {});");
-CheckError("(class extends Array {});");
-CheckError("(class C {});");
-CheckError("(class C exends Array {});");
-
-CheckOk("let = 1;");
-CheckOk("{ let = 1; }");
-CheckOk("function f() { let = 1; }");
-CheckOk("for (let = 1; let < 1; let++) {}");
diff --git a/test/mjsunit/es6/block-scope-class.js b/test/mjsunit/es6/block-scope-class.js
index 351feaa..7bbd49d 100644
--- a/test/mjsunit/es6/block-scope-class.js
+++ b/test/mjsunit/es6/block-scope-class.js
@@ -4,8 +4,6 @@
 
 // Test for conflicting variable bindings.
 
-// Flags: --harmony-sloppy --harmony-sloppy-function
-
 function AssertEqualsStrictAndSloppy(value, code) {
   assertEquals(value, eval("(function() {" + code + "})()"));
   assertEquals(value, eval("(function() { 'use strict'; " + code + "})()"));
diff --git a/test/mjsunit/harmony/block-scoping-sloppy.js b/test/mjsunit/es6/block-scoping-sloppy.js
similarity index 98%
rename from test/mjsunit/harmony/block-scoping-sloppy.js
rename to test/mjsunit/es6/block-scoping-sloppy.js
index 1785901..f5c5a63 100644
--- a/test/mjsunit/harmony/block-scoping-sloppy.js
+++ b/test/mjsunit/es6/block-scoping-sloppy.js
@@ -25,7 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Flags: --allow-natives-syntax --harmony-sloppy --harmony-sloppy-let --harmony-sloppy-function
+// Flags: --allow-natives-syntax
 // Test functionality of block scopes.
 
 // Hoisting of var declarations.
diff --git a/test/mjsunit/harmony/block-scoping-top-level-sloppy.js b/test/mjsunit/es6/block-scoping-top-level-sloppy.js
similarity index 91%
rename from test/mjsunit/harmony/block-scoping-top-level-sloppy.js
rename to test/mjsunit/es6/block-scoping-top-level-sloppy.js
index 6f6a8fe..2a3b903 100644
--- a/test/mjsunit/harmony/block-scoping-top-level-sloppy.js
+++ b/test/mjsunit/es6/block-scoping-top-level-sloppy.js
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 // Flags: --min-preparse-length=0
-// Flags: --harmony-sloppy --harmony-sloppy-let
 
 let xxx = 1;
 let f = undefined;
diff --git a/test/mjsunit/harmony/block-sloppy-function.js b/test/mjsunit/es6/block-sloppy-function.js
similarity index 98%
rename from test/mjsunit/harmony/block-sloppy-function.js
rename to test/mjsunit/es6/block-sloppy-function.js
index 2bea147..41063b4 100644
--- a/test/mjsunit/harmony/block-sloppy-function.js
+++ b/test/mjsunit/es6/block-sloppy-function.js
@@ -2,9 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Flags: --harmony-sloppy --harmony-sloppy-let
-// Flags: --harmony-sloppy-function
-
 // Test Annex B 3.3 semantics for functions declared in blocks in sloppy mode.
 // http://www.ecma-international.org/ecma-262/6.0/#sec-block-level-function-declarations-web-legacy-compatibility-semantics
 
diff --git a/test/mjsunit/es6/class-computed-property-names-super.js b/test/mjsunit/es6/class-computed-property-names-super.js
index cb9f251..b5a2ac9 100644
--- a/test/mjsunit/es6/class-computed-property-names-super.js
+++ b/test/mjsunit/es6/class-computed-property-names-super.js
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Flags: --harmony-sloppy
 // Flags: --allow-natives-syntax
 
 
diff --git a/test/mjsunit/es6/class-property-name-eval-arguments.js b/test/mjsunit/es6/class-property-name-eval-arguments.js
index 72ff60f..bbd05cc 100644
--- a/test/mjsunit/es6/class-property-name-eval-arguments.js
+++ b/test/mjsunit/es6/class-property-name-eval-arguments.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-sloppy
-
 
 (function Method() {
   class C {
diff --git a/test/mjsunit/es6/classes-derived-return-type.js b/test/mjsunit/es6/classes-derived-return-type.js
index 8283bcb..3f81a34 100644
--- a/test/mjsunit/es6/classes-derived-return-type.js
+++ b/test/mjsunit/es6/classes-derived-return-type.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-sloppy
-
 
 class Base {}
 
diff --git a/test/mjsunit/es6/classes.js b/test/mjsunit/es6/classes.js
index 4dabda8..fb77dbb 100644
--- a/test/mjsunit/es6/classes.js
+++ b/test/mjsunit/es6/classes.js
@@ -2,8 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Flags: --harmony-sloppy --harmony-function-name --allow-natives-syntax
-// Flags: --harmony-do-expressions
+// Flags: --allow-natives-syntax --harmony-do-expressions
 
 (function TestBasics() {
   var C = class C {}
diff --git a/test/mjsunit/es6/completion.js b/test/mjsunit/es6/completion.js
index 7559514..988e970 100644
--- a/test/mjsunit/es6/completion.js
+++ b/test/mjsunit/es6/completion.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-sloppy-let
-
 
 function assertUndef(x) {
   assertEquals(undefined, x);
diff --git a/test/mjsunit/es6/debug-blockscopes.js b/test/mjsunit/es6/debug-blockscopes.js
index 193ad70..bf04a0a 100644
--- a/test/mjsunit/es6/debug-blockscopes.js
+++ b/test/mjsunit/es6/debug-blockscopes.js
@@ -52,6 +52,7 @@
       listener_delegate(exec_state);
     }
   } catch (e) {
+    print(e, e.stack);
     exception = e;
   }
 }
@@ -147,10 +148,8 @@
   if (!scope.scopeObject().property('arguments').isUndefined()) {
     scope_size--;
   }
-  // Skip property with empty name.
-  if (!scope.scopeObject().property('').isUndefined()) {
-    scope_size--;
-  }
+  // Temporary variables introduced by the parser have not been materialized.
+  assertTrue(scope.scopeObject().property('').isUndefined());
 
   if (count != scope_size) {
     print('Names found in scope:');
@@ -380,16 +379,12 @@
 
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Block,
-                   debug.ScopeType.Block,
                    debug.ScopeType.Local,
                    debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({x:'y'}, 0, exec_state);
   // The function scope contains a temporary iteration variable, but it is
   // hidden to the debugger.
-  // TODO(adamk): This variable is only used to provide a TDZ for the enumerable
-  // expression and should not be visible to the debugger.
-  CheckScopeContent({x:undefined}, 1, exec_state);
 };
 for_loop_1();
 EndTest();
@@ -409,7 +404,6 @@
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Block,
                    debug.ScopeType.Block,
-                   debug.ScopeType.Block,
                    debug.ScopeType.Local,
                    debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
@@ -417,9 +411,6 @@
   CheckScopeContent({x:'y'}, 1, exec_state);
   // The function scope contains a temporary iteration variable, hidden to the
   // debugger.
-  // TODO(adamk): This variable is only used to provide a TDZ for the enumerable
-  // expression and should not be visible to the debugger.
-  CheckScopeContent({x:undefined}, 2, exec_state);
 };
 for_loop_2();
 EndTest();
@@ -436,13 +427,11 @@
 
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Block,
-                   debug.ScopeType.Block,
                    debug.ScopeType.Local,
                    debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({x:3}, 0, exec_state);
-  CheckScopeContent({x:3}, 1, exec_state);
-  CheckScopeContent({}, 2, exec_state);
+  CheckScopeContent({}, 1, exec_state);
 };
 for_loop_3();
 EndTest();
@@ -461,14 +450,12 @@
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Block,
                    debug.ScopeType.Block,
-                   debug.ScopeType.Block,
                    debug.ScopeType.Local,
                    debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({x:5}, 0, exec_state);
   CheckScopeContent({x:3}, 1, exec_state);
-  CheckScopeContent({x:3}, 2, exec_state);
-  CheckScopeContent({}, 3, exec_state);
+  CheckScopeContent({}, 2, exec_state);
 };
 for_loop_4();
 EndTest();
@@ -485,13 +472,11 @@
 
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Block,
-                   debug.ScopeType.Block,
                    debug.ScopeType.Local,
                    debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({x:3,y:5}, 0, exec_state);
-  CheckScopeContent({x:3,y:5}, 1, exec_state);
-  CheckScopeContent({}, 2, exec_state);
+  CheckScopeContent({}, 1, exec_state);
 };
 for_loop_5();
 EndTest();
diff --git a/test/mjsunit/es6/debug-evaluate-receiver-before-super.js b/test/mjsunit/es6/debug-evaluate-receiver-before-super.js
new file mode 100644
index 0000000..dc8ce2c
--- /dev/null
+++ b/test/mjsunit/es6/debug-evaluate-receiver-before-super.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
+
+// Test that debug-evaluate doesn't crash when this is used before super() call
+// in constructor.
+
+Debug = debug.Debug
+
+var result;
+
+function listener(event, exec_state, event_data, data)
+{
+  try {
+    if (event == Debug.DebugEvent.Break) {
+      result = exec_state.frame(0).evaluate("this.a").value();
+    }
+  } catch (e) {
+    result = e.message;
+  }
+}
+
+Debug.setListener(listener);
+
+class A { constructor () { this.a = 239; } }
+class B extends A {
+  constructor () {
+    debugger;
+    assertEquals("Cannot read property 'a' of undefined", result);
+    super();
+    debugger;
+    assertEquals(239, result);
+  }
+}
+new B();
+
+Debug.setListener(null);
diff --git a/test/mjsunit/es6/debug-promises/stepin-constructor.js b/test/mjsunit/es6/debug-promises/stepin-constructor.js
index 906969e..6914ae0 100644
--- a/test/mjsunit/es6/debug-promises/stepin-constructor.js
+++ b/test/mjsunit/es6/debug-promises/stepin-constructor.js
@@ -21,9 +21,9 @@
 Debug.setListener(listener);
 
 function resolver(resolve, reject) {
-  1;
-  2;
-  3;
+  print(1);
+  print(2);
+  print(3);
   resolve();
 }
 
@@ -35,9 +35,9 @@
 var expected_breaks = [
   "debugger;",
   "var p = new Promise(resolver);",
-  "1;",
-  "2;",
-  "3;",
+  "print(1);",
+  "print(2);",
+  "print(3);",
   "resolve();",
   "}",
   "Debug.setListener(null);"
diff --git a/test/mjsunit/es6/debug-scope-default-param-with-eval.js b/test/mjsunit/es6/debug-scope-default-param-with-eval.js
new file mode 100644
index 0000000..d4dc93f
--- /dev/null
+++ b/test/mjsunit/es6/debug-scope-default-param-with-eval.js
@@ -0,0 +1,61 @@
+// 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
+
+// Test that the parameter initialization block scope set up for
+// sloppy eval is visible to the debugger.
+
+var Debug = debug.Debug;
+var exception = null;
+var break_count = 0;
+
+function call_for_break() {
+  return 5;
+}
+
+function test(x = eval("var y = 7; debugger; y") + call_for_break()) {
+  return x;
+}
+
+function listener(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    var frame = exec_state.frame(0);
+    var block_scope;
+    if (break_count++ == 0) {
+      // Inside eval.
+      assertEquals([ debug.ScopeType.Eval,
+                     debug.ScopeType.Block,
+                     debug.ScopeType.Closure,
+                     debug.ScopeType.Script,
+                     debug.ScopeType.Global ],
+                   frame.allScopes().map(s => s.scopeType()));
+      exec_state.prepareStep(Debug.StepAction.StepOut);
+      block_scope = frame.scope(1);
+    } else {
+      // Outside of eval.
+      assertEquals([ debug.ScopeType.Block,
+                     debug.ScopeType.Local,
+                     debug.ScopeType.Script,
+                     debug.ScopeType.Global ],
+                   frame.allScopes().map(s => s.scopeType()));
+      block_scope = frame.scope(0);
+    }
+    assertTrue(block_scope.scopeObject().propertyNames().includes('y'));
+    assertEquals(7, block_scope.scopeObject().property('y').value().value());
+  } catch (e) {
+    print(e);
+    exception = e;
+  }
+}
+
+Debug.setListener(listener);
+
+assertEquals(12, test());
+
+Debug.setListener(null);
+
+assertNull(exception);
+assertEquals(2, break_count);
diff --git a/test/mjsunit/es6/debug-stepin-microtasks.js b/test/mjsunit/es6/debug-stepin-microtasks.js
index 6a7c553..e541f0f 100644
--- a/test/mjsunit/es6/debug-stepin-microtasks.js
+++ b/test/mjsunit/es6/debug-stepin-microtasks.js
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Flags: --harmony-object-observe
 // Flags: --allow-natives-syntax --expose-debug-as debug
 
 Debug = debug.Debug
@@ -46,6 +45,7 @@
   .then(Boolean) // Should skip stepping into native.
   .then(promise2)
   .catch(promise3)
+  .then(promise4)
   .catch(function(e) {
     %AbortJS("FAIL: uncaught exception " + e);
   });
@@ -60,36 +60,16 @@
 }
 
 function promise3() {
-  installObservers(); // Break 4. StepOver.
-  return break_count; // Break 5.
-} // Break 6.
-
-function installObservers() {
-  var dummy = {};
-  Object.observe(dummy, observer1);
-  Object.observe(dummy, Object); // Should skip stepping into native.
-  Object.observe(dummy, Boolean); // Should skip stepping into native.
-  Object.observe(dummy, observer2);
-  dummy.foo = 1;
-}
-
-function observer1() {
-  return exception || 3; // Break 7.
-} // Break 8.
-
-function observer2() {
-  Promise.resolve().then(promise4); // Break 9. StepOver.
-  return break_count + 1; // Break 10.
-} // Break 11.
+  return break_count; // Break 4.
+} // Break 5.
 
 function promise4() {
-  finalize(); // Break 12. StepOver.
-  return 0; // Break 13.
-} // Break 14. StepOver.
+  finalize(); // Break 6. StepOver.
+  return 0; // Break 7.
+} // Break 8. StepOver.
 
 function finalize() {
-  var dummy = {};
-  Object.observe(dummy, function() {
+  Promise.resolve().then(function() {
     if (expected_breaks !== break_count) {
       %AbortJS("FAIL: expected <" + expected_breaks + "> breaks instead of <" +
                break_count + ">");
@@ -98,5 +78,4 @@
       %AbortJS("FAIL: exception: " + exception);
     }
   });
-  dummy.foo = 1;
 }
diff --git a/test/mjsunit/es6/debug-stepin-proxies.js b/test/mjsunit/es6/debug-stepin-proxies.js
index 4e71c79..72c01f0 100644
--- a/test/mjsunit/es6/debug-stepin-proxies.js
+++ b/test/mjsunit/es6/debug-stepin-proxies.js
@@ -54,7 +54,7 @@
 
 assertEquals([
   "a0",
-  "b17", "h4b20", "i2b20",  // [[Has]]
+  "b17", "h4b17", "i2b17",  // [[Has]]
   "c15", "j4c15", "k2c15",  // [[Get]]
   "d0", "l4d11", "m2d11",   // [[Set]]
   "g0"
diff --git a/test/mjsunit/es6/debug-stepnext-for.js b/test/mjsunit/es6/debug-stepnext-for.js
index 9d5641a..d425a46 100644
--- a/test/mjsunit/es6/debug-stepnext-for.js
+++ b/test/mjsunit/es6/debug-stepnext-for.js
@@ -11,6 +11,8 @@
 
 var s = 0;
 var a = [1, 2, 3];
+var b = [1, 2, 3, 4];
+var null_value = null;
 var i = 0;
 
 function f() {
@@ -18,11 +20,11 @@
   debugger;                      // Break a
   var j;                         // Break b
 
-  for (var i in null) {          // Break c
+  for (var i in null_value) {    // Break c
     s += a[i];
   }
 
-  for (j in null) {              // Break d
+  for (j in null_value) {        // Break d
     s += a[j];
   }
 
@@ -46,7 +48,7 @@
     s += j;                      // Break I
   }
 
-  for (let i of a) {             // Break j
+  for (let i  of  a) {           // Break j
     s += i;                      // Break J
   }
 
@@ -61,6 +63,11 @@
   for (let i = 0; i < 3; i++) {  // Break m
     s += a[i];                   // Break M
   }
+
+  for (let i of a) {}            // Break n
+
+  [1, ...a]                      // Break o
+
 }                                // Break y
 
 function listener(event, exec_state, event_data, data) {
@@ -103,17 +110,21 @@
   // For-in-let: get enumerable, next, body, next,  ...
   "g16","g11","G4","g11","G4","g11","G4","g11",
   // For-of-var: [Symbol.iterator](), next(), body, next(), body, ...
-  "h16","h14","h15","H4","h15","H4","h15","H4","h15",
+  "h16","h13","H4","h13","H4","h13","H4","h13",
   // For-of: [Symbol.iterator](), next(), body, next(), body, ...
-  "i12","i10","i11","I4","i11","I4","i11","I4","i11",
+  "i12","i9","I4","i9","I4","i9","I4","i9",
   // For-of-let: [Symbol.iterator](), next(), body, next(), ...
-  "j16","j14","j15","J4","j15","J4","j15","J4","j15",
+  "j18","j14","J4","j14","J4","j14","J4","j14",
   // For-var: init, condition, body, next, condition, body, ...
   "k15","k20","K4","k26","k20","K4","k26","k20","K4","k26","k20",
   // For: init, condition, body, next, condition, body, ...
   "l7","l16","L4","l22","l16","L4","l22","l16","L4","l22","l16",
   // For-let: init, condition, body, next, condition, body, ...
   "m15","m20","M4","m26","m20","M4","m26","m20","M4","m26","m20",
+  // For-of, empty: [Symbol.iterator](), next() once
+  "n16", "n13",
+  // Spread: expression statement, spread
+  "o2", "o9",
   // Exit.
   "y0","z0",
 ]
diff --git a/test/mjsunit/es6/generators-objects.js b/test/mjsunit/es6/generators-objects.js
index a0c3b80..2d23841 100644
--- a/test/mjsunit/es6/generators-objects.js
+++ b/test/mjsunit/es6/generators-objects.js
@@ -87,3 +87,29 @@
   TestNonGenerator(g.prototype);
 }
 TestGeneratorObjectMethods();
+
+
+function TestPrototype() {
+  function* g() { }
+
+  let g_prototype = g.prototype;
+  assertEquals([], Reflect.ownKeys(g_prototype));
+
+  let generator_prototype = Object.getPrototypeOf(g_prototype);
+  assertSame(generator_prototype, Object.getPrototypeOf(g).prototype);
+
+  // Unchanged .prototype
+  assertSame(g_prototype, Object.getPrototypeOf(g()));
+
+  // Custom object as .prototype
+  {
+    let proto = {};
+    g.prototype = proto;
+    assertSame(proto, Object.getPrototypeOf(g()));
+  }
+
+  // Custom non-object as .prototype
+  g.prototype = null;
+  assertSame(generator_prototype, Object.getPrototypeOf(g()));
+}
+TestPrototype();
diff --git a/test/mjsunit/es6/microtask-delivery.js b/test/mjsunit/es6/microtask-delivery.js
index 01b971d..6b239be 100644
--- a/test/mjsunit/es6/microtask-delivery.js
+++ b/test/mjsunit/es6/microtask-delivery.js
@@ -25,7 +25,6 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Flags: --harmony-object-observe
 // Flags: --allow-natives-syntax
 
 var ordering = [];
@@ -71,22 +70,6 @@
   };
 }
 
-function newObserver(id, fn, obj) {
-  var observer = {
-    value: 1,
-    recordCounts: []
-  };
-
-  Object.observe(observer, function(records) {
-    ordering.push('o' + id);
-    observer.recordCounts.push(records.length);
-    if (fn) fn();
-  });
-
-  return observer;
-}
-
-
 (function PromiseThens() {
   reset();
 
@@ -98,72 +81,3 @@
 
   assertOrdering(['p1', 'p2', 'p1:1', 'p2:1']);
 })();
-
-
-(function ObserversBatch() {
-  reset();
-
-  var p1 = newPromise(1);
-  var p2 = newPromise(2);
-  var p3 = newPromise(3);
-
-  var ob1 = newObserver(1);
-  var ob2 = newObserver(2, function() {
-    ob3.value++;
-    p3.resolve();
-    ob1.value++;
-  });
-  var ob3 = newObserver(3);
-
-  p1.resolve();
-  ob1.value++;
-  p2.resolve();
-  ob2.value++;
-
-  assertOrdering(['p1', 'o1', 'o2', 'p2', 'o1', 'o3', 'p3']);
-  assertArrayValues([1, 1], ob1.recordCounts);
-  assertArrayValues([1], ob2.recordCounts);
-  assertArrayValues([1], ob3.recordCounts);
-})();
-
-
-(function ObserversGetAllRecords() {
-  reset();
-
-  var p1 = newPromise(1);
-  var p2 = newPromise(2);
-  var ob1 = newObserver(1, function() {
-    ob2.value++;
-  });
-  var ob2 = newObserver(2);
-
-  p1.resolve();
-  ob1.value++;
-  p2.resolve();
-  ob2.value++;
-
-  assertOrdering(['p1', 'o1', 'o2', 'p2']);
-  assertArrayValues([1], ob1.recordCounts);
-  assertArrayValues([2], ob2.recordCounts);
-})();
-
-
-(function NewObserverDeliveryGetsNewMicrotask() {
-  reset();
-
-  var p1 = newPromise(1);
-  var p2 = newPromise(2);
-  var ob1 = newObserver(1);
-  var ob2 = newObserver(2, function() {
-    ob1.value++;
-  });
-
-  p1.resolve();
-  ob1.value++;
-  p2.resolve();
-  ob2.value++;
-
-  assertOrdering(['p1', 'o1', 'o2', 'p2', 'o1']);
-  assertArrayValues([1, 1], ob1.recordCounts);
-  assertArrayValues([1], ob2.recordCounts);
-})();
diff --git a/test/mjsunit/es6/mirror-collections.js b/test/mjsunit/es6/mirror-collections.js
index 81a98b8..4232ef9 100644
--- a/test/mjsunit/es6/mirror-collections.js
+++ b/test/mjsunit/es6/mirror-collections.js
@@ -88,16 +88,21 @@
 assertSame(o2, values[0]);
 assertEquals(undefined, values[1]);
 
+function initWeakMap(weakMap) {
+  weakMap.set(o1, 11);
+  weakMap.set(new Object(), 22);
+  weakMap.set(o3, 33);
+  weakMap.set(new Object(), 44);
+  var weakMapMirror = debug.MakeMirror(weakMap);
+  testMapMirror(weakMapMirror);
+  weakMap.set(new Object(), 55);
+  assertTrue(weakMapMirror.entries().length <= 5);
+  return weakMapMirror;
+}
+
 // Test the mirror object for WeakMaps
 var weakMap = new WeakMap();
-weakMap.set(o1, 11);
-weakMap.set(new Object(), 22);
-weakMap.set(o3, 33);
-weakMap.set(new Object(), 44);
-var weakMapMirror = debug.MakeMirror(weakMap);
-testMapMirror(weakMapMirror);
-weakMap.set(new Object(), 55);
-assertTrue(weakMapMirror.entries().length <= 5);
+var weakMapMirror = initWeakMap(weakMap);
 gc();
 
 function testWeakMapEntries(weakMapMirror) {
@@ -121,18 +126,23 @@
 
 testWeakMapEntries(weakMapMirror);
 
+function initWeakSet(weakSet) {
+  weakSet.add(o1);
+  weakSet.add(new Object());
+  weakSet.add(o2);
+  weakSet.add(new Object());
+  weakSet.add(new Object());
+  weakSet.add(o3);
+  weakSet.delete(o2);
+  var weakSetMirror =  debug.MakeMirror(weakSet);
+  testSetMirror(weakSetMirror);
+  assertTrue(weakSetMirror.values().length <= 5);
+  return weakSetMirror;
+}
+
 // Test the mirror object for WeakSets
 var weakSet = new WeakSet();
-weakSet.add(o1);
-weakSet.add(new Object());
-weakSet.add(o2);
-weakSet.add(new Object());
-weakSet.add(new Object());
-weakSet.add(o3);
-weakSet.delete(o2);
-var weakSetMirror = debug.MakeMirror(weakSet);
-testSetMirror(weakSetMirror);
-assertTrue(weakSetMirror.values().length <= 5);
+var weakSetMirror = initWeakSet(weakSet);
 gc();
 
 function testWeakSetValues(weakSetMirror) {
diff --git a/test/mjsunit/es6/proxies-for.js b/test/mjsunit/es6/proxies-for.js
index 5b81845..a171227 100644
--- a/test/mjsunit/es6/proxies-for.js
+++ b/test/mjsunit/es6/proxies-for.js
@@ -209,10 +209,15 @@
   assertThrowsEquals(() => {keys(proxy)}, "error");
 })();
 
-
-(function () {
-  var symbol = Symbol();
-  var p = new Proxy({}, {ownKeys() { return ["1", symbol, "2"] }});
-  assertEquals(["1","2"], Object.getOwnPropertyNames(p));
-  assertEquals([symbol], Object.getOwnPropertySymbols(p));
+(function testNestedProxy() {
+  var handler = {
+    ownKeys() {
+      return ['c'];
+    },
+    getOwnPropertyDescriptor() { return {configurable: true, enumerable: true } }
+  }
+  var proxy = new Proxy({}, handler);
+  var proxy2 = new Proxy(proxy, {});
+  assertEquals(['c'], keys(proxy));
+  assertEquals(['c'], keys(proxy2));
 })();
diff --git a/test/mjsunit/es6/proxies-keys.js b/test/mjsunit/es6/proxies-keys.js
index 7344032..65dea6a 100644
--- a/test/mjsunit/es6/proxies-keys.js
+++ b/test/mjsunit/es6/proxies-keys.js
@@ -37,3 +37,14 @@
 handler.ownKeys = undefined;
 assertEquals(["target"], Object.keys(proxy));
 assertEquals(["target"], Object.keys(target));
+
+var proxy2 = new Proxy(proxy, {});
+assertEquals(["target"], Object.keys(proxy2));
+
+
+(function testForSymbols() {
+  var symbol = Symbol();
+  var p = new Proxy({}, {ownKeys() { return ["1", symbol, "2"] }});
+  assertEquals(["1","2"], Object.getOwnPropertyNames(p));
+  assertEquals([symbol], Object.getOwnPropertySymbols(p));
+})();
diff --git a/test/mjsunit/es6/reflect-define-property.js b/test/mjsunit/es6/reflect-define-property.js
index b19c5aa..d62a934 100644
--- a/test/mjsunit/es6/reflect-define-property.js
+++ b/test/mjsunit/es6/reflect-define-property.js
@@ -441,8 +441,7 @@
 }
 
 
-// Test runtime calls to DefineDataPropertyUnchecked and
-// DefineAccessorPropertyUnchecked - make sure we don't
+// Test runtime calls to DefineAccessorPropertyUnchecked - make sure we don't
 // crash.
 try {
   %DefineAccessorPropertyUnchecked(0, 0, 0, 0, 0);
@@ -451,29 +450,11 @@
 }
 
 try {
-  %DefineDataPropertyUnchecked(0, 0, 0, 0);
-} catch (e) {
-  assertTrue(/illegal access/.test(e));
-}
-
-try {
-  %DefineDataPropertyUnchecked(null, null, null, null);
-} catch (e) {
-  assertTrue(/illegal access/.test(e));
-}
-
-try {
   %DefineAccessorPropertyUnchecked(null, null, null, null, null);
 } catch (e) {
   assertTrue(/illegal access/.test(e));
 }
 
-try {
-  %DefineDataPropertyUnchecked({}, null, null, null);
-} catch (e) {
-  assertTrue(/illegal access/.test(e));
-}
-
 // Defining properties null should fail even when we have
 // other allowed values
 try {
@@ -482,12 +463,6 @@
   assertTrue(/illegal access/.test(e));
 }
 
-try {
-  %DefineDataPropertyUnchecked(null, 'foo', 0, 0);
-} catch (e) {
-  assertTrue(/illegal access/.test(e));
-}
-
 // Test that all possible differences in step 6 in DefineOwnProperty are
 // exercised, i.e., any difference in the given property descriptor and the
 // existing properties should not return true, but throw an error if the
diff --git a/test/mjsunit/es6/regress/regress-3750.js b/test/mjsunit/es6/regress/regress-3750.js
deleted file mode 100644
index 10509bf..0000000
--- a/test/mjsunit/es6/regress/regress-3750.js
+++ /dev/null
@@ -1,9 +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.
-//
-// Flags: --harmony-object-observe
-
-'use strict';
-class Example { }
-Object.observe(Example.prototype, function(){});
diff --git a/test/mjsunit/harmony/regress/regress-4482.js b/test/mjsunit/es6/regress/regress-4482.js
similarity index 91%
rename from test/mjsunit/harmony/regress/regress-4482.js
rename to test/mjsunit/es6/regress/regress-4482.js
index 2472b46..d813d21 100644
--- a/test/mjsunit/harmony/regress/regress-4482.js
+++ b/test/mjsunit/es6/regress/regress-4482.js
@@ -1,8 +1,6 @@
 // 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-sloppy
 
 assertEquals("function", (function f() { f = 42; return typeof f })());
 assertEquals("function",
diff --git a/test/mjsunit/es6/regress/regress-468661.js b/test/mjsunit/es6/regress/regress-468661.js
index 4a42350..4a58a71 100644
--- a/test/mjsunit/es6/regress/regress-468661.js
+++ b/test/mjsunit/es6/regress/regress-468661.js
@@ -9,7 +9,8 @@
 var break_count = 0;
 
 var expected_values =
-  [ReferenceError, undefined, 0, 0, 0, 0, 1, ReferenceError, ReferenceError];
+  [ReferenceError, undefined, 0, 0, 0, 0, 1,
+   ReferenceError, ReferenceError];
 
 function listener(event, exec_state, event_data, data) {
   try {
@@ -39,7 +40,6 @@
         assertTrue(v instanceof ReferenceError);
       } else {
         assertSame(expected_values[break_count], v);
-
       }
       ++break_count;
 
diff --git a/test/mjsunit/es6/spread-call-new-class.js b/test/mjsunit/es6/spread-call-new-class.js
index 1fdf25b..de88cff 100644
--- a/test/mjsunit/es6/spread-call-new-class.js
+++ b/test/mjsunit/es6/spread-call-new-class.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-sloppy
-
 
 (function testConstructClassStrict() {
   "use strict";
diff --git a/test/mjsunit/es6/spread-call-super-property.js b/test/mjsunit/es6/spread-call-super-property.js
index b298a69..a85ea41 100644
--- a/test/mjsunit/es6/spread-call-super-property.js
+++ b/test/mjsunit/es6/spread-call-super-property.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-sloppy
-
 (function testCallSuperPropertyStrict() {
   "use strict";
   class BaseClass {
diff --git a/test/mjsunit/es6/super.js b/test/mjsunit/es6/super.js
index a2ba1e8..4c80ce7 100644
--- a/test/mjsunit/es6/super.js
+++ b/test/mjsunit/es6/super.js
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 // Flags: --allow-natives-syntax
-// Flags: --harmony-sloppy
 
 (function TestSuperNamedLoads() {
   function Base() { }
diff --git a/test/mjsunit/es6/tail-call.js b/test/mjsunit/es6/tail-call.js
index d0d00f4..6ecf04f 100644
--- a/test/mjsunit/es6/tail-call.js
+++ b/test/mjsunit/es6/tail-call.js
@@ -3,6 +3,8 @@
 // found in the LICENSE file.
 
 // Flags: --allow-natives-syntax --harmony-tailcalls
+// Flags: --harmony-do-expressions
+
 "use strict";
 
 Error.prepareStackTrace = (error,stack) => {
@@ -259,9 +261,8 @@
   }
   %NeverOptimizeFunction(g);
 
-  var context = 10;
   function f(v) {
-    return g(context);
+    return g();
   }
   %SetForceInlineFlag(f);
 
@@ -319,10 +320,57 @@
     return f([f, g3, test], 13), f([f, test], 153);
   }
 
+  function g4(a) {
+    return f([f, g4, test], false) ||
+        (f([f, g4, test], true) && f([f, test], true));
+  }
+
+  function g5(a) {
+    return f([f, g5, test], true) &&
+        (f([f, g5, test], false) || f([f, test], true));
+  }
+
+  function g6(a) {
+    return f([f, g6, test], 13), f([f, g6, test], 42),
+        f([f, test], 153);
+  }
+
+  function g7(a) {
+    return f([f, g7, test], false) ||
+        (f([f, g7, test], false) ? f([f, test], true)
+             : f([f, test], true));
+  }
+
+  function g8(a) {
+    return f([f, g8, test], false) || f([f, g8, test], true) &&
+        f([f, test], true);
+  }
+
+  function g9(a) {
+    return f([f, g9, test], true) && f([f, g9, test], false) ||
+        f([f, test], true);
+  }
+
+  function g10(a) {
+    return f([f, g10, test], true) && f([f, g10, test], false) ||
+        f([f, g10, test], true) ?
+            f([f, g10, test], true) && f([f, g10, test], false) ||
+                f([f, test], true) :
+            f([f, g10, test], true) && f([f, g10, test], false) ||
+                f([f, test], true);
+  }
+
   function test() {
     assertEquals(true, g1());
     assertEquals(true, g2());
     assertEquals(153, g3());
+    assertEquals(true, g4());
+    assertEquals(true, g5());
+    assertEquals(153, g6());
+    assertEquals(true, g7());
+    assertEquals(true, g8());
+    assertEquals(true, g9());
+    assertEquals(true, g10());
   }
   test();
   test();
@@ -534,9 +582,34 @@
     return (() => f_153([f_153, test]))();
   }
 
+  function g3(a) {
+    var closure = () => f([f, closure, test], true)
+                              ? f_153([f_153, test])
+                              : f_153([f_153, test]);
+    return closure();
+  }
+
   function test() {
     assertEquals(153, g1());
     assertEquals(153, g2());
+    assertEquals(153, g3());
+  }
+  test();
+  test();
+  %OptimizeFunctionOnNextCall(test);
+  test();
+})();
+
+
+// Test tail calls from do expressions.
+(function () {
+  function g1(a) {
+    var a = do { return f_153([f_153, test]); 42; };
+    return a;
+  }
+
+  function test() {
+    assertEquals(153, g1());
   }
   test();
   test();
diff --git a/test/mjsunit/es7/object-observe-debug-event.js b/test/mjsunit/es7/object-observe-debug-event.js
deleted file mode 100644
index 06123b8..0000000
--- a/test/mjsunit/es7/object-observe-debug-event.js
+++ /dev/null
@@ -1,52 +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.
-
-// Flags: --harmony-object-observe
-// Flags: --expose-debug-as debug
-
-Debug = debug.Debug;
-
-var base_id = -1;
-var exception = null;
-var expected = [
-  "enqueue #1",
-  "willHandle #1",
-  "didHandle #1",
-];
-
-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;
-    assertEquals("Object.observe", event_data.name());
-    assertLog(event_data.type() + " #" + id);
-  } catch (e) {
-    print(e + e.stack)
-    exception = e;
-  }
-}
-
-Debug.setListener(listener);
-
-var obj = {};
-Object.observe(obj, function(changes) {
-  print(change.type + " " + change.name + " " + change.oldValue);
-});
-
-obj.foo = 1;
-obj.zoo = 2;
-obj.foo = 3;
-
-assertNull(exception);
diff --git a/test/mjsunit/es7/object-observe-runtime.js b/test/mjsunit/es7/object-observe-runtime.js
deleted file mode 100644
index 1a07141..0000000
--- a/test/mjsunit/es7/object-observe-runtime.js
+++ /dev/null
@@ -1,19 +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.
-
-// Flags: --harmony-object-observe
-// Flags: --allow-natives-syntax
-
-// These tests are meant to ensure that that the Object.observe runtime
-// functions are hardened.
-
-var obj = {};
-%SetIsObserved(obj);
-assertThrows(function() {
-  %SetIsObserved(obj);
-});
-
-assertThrows(function() {
-  %SetIsObserved(this);
-});
diff --git a/test/mjsunit/es7/object-observe.js b/test/mjsunit/es7/object-observe.js
deleted file mode 100644
index a558c51..0000000
--- a/test/mjsunit/es7/object-observe.js
+++ /dev/null
@@ -1,1865 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --harmony-object-observe
-// Flags: --allow-natives-syntax
-
-var allObservers = [];
-function reset() {
-  allObservers.forEach(function(observer) { observer.reset(); });
-}
-
-function stringifyNoThrow(arg) {
-  try {
-    return JSON.stringify(arg);
-  } catch (e) {
-    return '{<circular reference>}';
-  }
-}
-
-function createObserver() {
-  "use strict";  // So that |this| in callback can be undefined.
-
-  var observer = {
-    records: undefined,
-    callbackCount: 0,
-    reset: function() {
-      this.records = undefined;
-      this.callbackCount = 0;
-    },
-    assertNotCalled: function() {
-      assertEquals(undefined, this.records);
-      assertEquals(0, this.callbackCount);
-    },
-    assertCalled: function() {
-      assertEquals(1, this.callbackCount);
-    },
-    assertRecordCount: function(count) {
-      this.assertCalled();
-      assertEquals(count, this.records.length);
-    },
-    assertCallbackRecords: function(recs) {
-      this.assertRecordCount(recs.length);
-      for (var i = 0; i < recs.length; i++) {
-        if ('name' in recs[i]) recs[i].name = String(recs[i].name);
-        print(i, stringifyNoThrow(this.records[i]), stringifyNoThrow(recs[i]));
-        assertSame(this.records[i].object, recs[i].object);
-        assertEquals('string', typeof recs[i].type);
-        assertPropertiesEqual(this.records[i], recs[i]);
-      }
-    }
-  };
-
-  observer.callback = function(r) {
-    assertEquals(undefined, this);
-    assertEquals('object', typeof r);
-    assertTrue(r instanceof Array)
-    observer.records = r;
-    observer.callbackCount++;
-  };
-
-  observer.reset();
-  allObservers.push(observer);
-  return observer;
-}
-
-var observer = createObserver();
-var observer2 = createObserver();
-
-assertEquals("function", typeof observer.callback);
-assertEquals("function", typeof observer2.callback);
-
-var obj = {};
-
-function frozenFunction() {}
-Object.freeze(frozenFunction);
-var nonFunction = {};
-var changeRecordWithAccessor = { type: 'foo' };
-var recordCreated = false;
-Object.defineProperty(changeRecordWithAccessor, 'name', {
-  get: function() {
-    recordCreated = true;
-    return "bar";
-  },
-  enumerable: true
-})
-
-
-// Object.observe
-assertThrows(function() { Object.observe("non-object", observer.callback); },
-             TypeError);
-assertThrows(function() { Object.observe(this, observer.callback); },
-             TypeError);
-assertThrows(function() { Object.observe(obj, nonFunction); }, TypeError);
-assertThrows(function() { Object.observe(obj, frozenFunction); }, TypeError);
-assertEquals(obj, Object.observe(obj, observer.callback, [1]));
-assertEquals(obj, Object.observe(obj, observer.callback, [true]));
-assertEquals(obj, Object.observe(obj, observer.callback, ['foo', null]));
-assertEquals(obj, Object.observe(obj, observer.callback, [undefined]));
-assertEquals(obj, Object.observe(obj, observer.callback,
-             ['foo', 'bar', 'baz']));
-assertEquals(obj, Object.observe(obj, observer.callback, []));
-assertEquals(obj, Object.observe(obj, observer.callback, undefined));
-assertEquals(obj, Object.observe(obj, observer.callback));
-
-// Object.unobserve
-assertThrows(function() { Object.unobserve(4, observer.callback); }, TypeError);
-assertThrows(function() { Object.unobserve(this, observer.callback); },
-             TypeError);
-assertThrows(function() { Object.unobserve(obj, nonFunction); }, TypeError);
-assertEquals(obj, Object.unobserve(obj, observer.callback));
-
-
-// Object.getNotifier
-var notifier = Object.getNotifier(obj);
-assertSame(notifier, Object.getNotifier(obj));
-assertEquals(null, Object.getNotifier(Object.freeze({})));
-assertThrows(function() { Object.getNotifier(this) }, TypeError);
-assertFalse(notifier.hasOwnProperty('notify'));
-assertEquals([], Object.keys(notifier));
-var notifyDesc = Object.getOwnPropertyDescriptor(notifier.__proto__, 'notify');
-assertTrue(notifyDesc.configurable);
-assertTrue(notifyDesc.writable);
-assertFalse(notifyDesc.enumerable);
-assertThrows(function() { notifier.notify({}); }, TypeError);
-assertThrows(function() { notifier.notify({ type: 4 }); }, TypeError);
-
-assertThrows(function() { notifier.performChange(1, function(){}); }, TypeError);
-assertThrows(function() { notifier.performChange(undefined, function(){}); }, TypeError);
-assertThrows(function() { notifier.performChange('foo', undefined); }, TypeError);
-assertThrows(function() { notifier.performChange('foo', 'bar'); }, TypeError);
-var global = this;
-notifier.performChange('foo', function() {
-  assertEquals(global, this);
-});
-
-var notify = notifier.notify;
-assertThrows(function() { notify.call(undefined, { type: 'a' }); }, TypeError);
-assertThrows(function() { notify.call(null, { type: 'a' }); }, TypeError);
-assertThrows(function() { notify.call(5, { type: 'a' }); }, TypeError);
-assertThrows(function() { notify.call('hello', { type: 'a' }); }, TypeError);
-assertThrows(function() { notify.call(false, { type: 'a' }); }, TypeError);
-assertThrows(function() { notify.call({}, { type: 'a' }); }, TypeError);
-assertFalse(recordCreated);
-notifier.notify(changeRecordWithAccessor);
-assertFalse(recordCreated);  // not observed yet
-
-
-// Object.deliverChangeRecords
-assertThrows(function() { Object.deliverChangeRecords(nonFunction); }, TypeError);
-
-Object.observe(obj, observer.callback);
-
-
-// notify uses to [[CreateOwnProperty]] to create changeRecord;
-reset();
-var protoExpandoAccessed = false;
-Object.defineProperty(Object.prototype, 'protoExpando',
-  {
-    configurable: true,
-    set: function() { protoExpandoAccessed = true; }
-  }
-);
-notifier.notify({ type: 'foo', protoExpando: 'val'});
-assertFalse(protoExpandoAccessed);
-delete Object.prototype.protoExpando;
-Object.deliverChangeRecords(observer.callback);
-
-
-// Multiple records are delivered.
-reset();
-notifier.notify({
-  type: 'update',
-  name: 'foo',
-  expando: 1
-});
-
-notifier.notify({
-  object: notifier,  // object property is ignored
-  type: 'delete',
-  name: 'bar',
-  expando2: 'str'
-});
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: obj, name: 'foo', type: 'update', expando: 1 },
-  { object: obj, name: 'bar', type: 'delete', expando2: 'str' }
-]);
-
-// Non-string accept values are coerced to strings
-reset();
-Object.observe(obj, observer.callback, [true, 1, null, undefined]);
-notifier = Object.getNotifier(obj);
-notifier.notify({ type: 'true' });
-notifier.notify({ type: 'false' });
-notifier.notify({ type: '1' });
-notifier.notify({ type: '-1' });
-notifier.notify({ type: 'null' });
-notifier.notify({ type: 'nill' });
-notifier.notify({ type: 'undefined' });
-notifier.notify({ type: 'defined' });
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: obj, type: 'true' },
-  { object: obj, type: '1' },
-  { object: obj, type: 'null' },
-  { object: obj, type: 'undefined' }
-]);
-
-// No delivery takes place if no records are pending
-reset();
-Object.deliverChangeRecords(observer.callback);
-observer.assertNotCalled();
-
-
-// Multiple observation has no effect.
-reset();
-Object.observe(obj, observer.callback);
-Object.observe(obj, observer.callback);
-Object.getNotifier(obj).notify({
-  type: 'update',
-});
-Object.deliverChangeRecords(observer.callback);
-observer.assertCalled();
-
-
-// Observation can be stopped.
-reset();
-Object.unobserve(obj, observer.callback);
-Object.getNotifier(obj).notify({
-  type: 'update',
-});
-Object.deliverChangeRecords(observer.callback);
-observer.assertNotCalled();
-
-
-// Multiple unobservation has no effect
-reset();
-Object.unobserve(obj, observer.callback);
-Object.unobserve(obj, observer.callback);
-Object.getNotifier(obj).notify({
-  type: 'update',
-});
-Object.deliverChangeRecords(observer.callback);
-observer.assertNotCalled();
-
-
-// Re-observation works and only includes changeRecords after of call.
-reset();
-Object.getNotifier(obj).notify({
-  type: 'update',
-});
-Object.observe(obj, observer.callback);
-Object.getNotifier(obj).notify({
-  type: 'update',
-});
-records = undefined;
-Object.deliverChangeRecords(observer.callback);
-observer.assertRecordCount(1);
-
-// Get notifier prior to observing
-reset();
-var obj = {};
-Object.getNotifier(obj);
-Object.observe(obj, observer.callback);
-obj.id = 1;
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: obj, type: 'add', name: 'id' },
-]);
-
-// The empty-string property is observable
-reset();
-var obj = {};
-Object.observe(obj, observer.callback);
-obj[''] = '';
-obj[''] = ' ';
-delete obj[''];
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: obj, type: 'add', name: '' },
-  { object: obj, type: 'update', name: '', oldValue: '' },
-  { object: obj, type: 'delete', name: '', oldValue: ' ' },
-]);
-
-// Object.preventExtensions
-reset();
-var obj = { foo: 'bar'};
-Object.observe(obj, observer.callback);
-obj.baz = 'bat';
-Object.preventExtensions(obj);
-
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: obj, type: 'add', name: 'baz' },
-  { object: obj, type: 'preventExtensions' },
-]);
-
-reset();
-var obj = { foo: 'bar'};
-Object.preventExtensions(obj);
-Object.observe(obj, observer.callback);
-Object.preventExtensions(obj);
-Object.deliverChangeRecords(observer.callback);
-observer.assertNotCalled();
-
-// Object.freeze
-reset();
-var obj = { a: 'a' };
-Object.defineProperty(obj, 'b', {
-  writable: false,
-  configurable: true,
-  value: 'b'
-});
-Object.defineProperty(obj, 'c', {
-  writable: true,
-  configurable: false,
-  value: 'c'
-});
-Object.defineProperty(obj, 'd', {
-  writable: false,
-  configurable: false,
-  value: 'd'
-});
-Object.observe(obj, observer.callback);
-Object.freeze(obj);
-
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: obj, type: 'preventExtensions' },
-  { object: obj, type: 'reconfigure', name: 'a' },
-  { object: obj, type: 'reconfigure', name: 'b' },
-  { object: obj, type: 'reconfigure', name: 'c' },
-]);
-
-reset();
-var obj = { foo: 'bar'};
-Object.freeze(obj);
-Object.observe(obj, observer.callback);
-Object.freeze(obj);
-Object.deliverChangeRecords(observer.callback);
-observer.assertNotCalled();
-
-// Object.seal
-reset();
-var obj = { a: 'a' };
-Object.defineProperty(obj, 'b', {
-  writable: false,
-  configurable: true,
-  value: 'b'
-});
-Object.defineProperty(obj, 'c', {
-  writable: true,
-  configurable: false,
-  value: 'c'
-});
-Object.defineProperty(obj, 'd', {
-  writable: false,
-  configurable: false,
-  value: 'd'
-});
-Object.observe(obj, observer.callback);
-Object.seal(obj);
-
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: obj, type: 'preventExtensions' },
-  { object: obj, type: 'reconfigure', name: 'a' },
-  { object: obj, type: 'reconfigure', name: 'b' },
-]);
-
-reset();
-var obj = { foo: 'bar'};
-Object.seal(obj);
-Object.observe(obj, observer.callback);
-Object.seal(obj);
-Object.deliverChangeRecords(observer.callback);
-observer.assertNotCalled();
-
-// Observing a continuous stream of changes, while itermittantly unobserving.
-reset();
-var obj = {};
-Object.observe(obj, observer.callback);
-Object.getNotifier(obj).notify({
-  type: 'update',
-  val: 1
-});
-
-Object.unobserve(obj, observer.callback);
-Object.getNotifier(obj).notify({
-  type: 'update',
-  val: 2
-});
-
-Object.observe(obj, observer.callback);
-Object.getNotifier(obj).notify({
-  type: 'update',
-  val: 3
-});
-
-Object.unobserve(obj, observer.callback);
-Object.getNotifier(obj).notify({
-  type: 'update',
-  val: 4
-});
-
-Object.observe(obj, observer.callback);
-Object.getNotifier(obj).notify({
-  type: 'update',
-  val: 5
-});
-
-Object.unobserve(obj, observer.callback);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: obj, type: 'update', val: 1 },
-  { object: obj, type: 'update', val: 3 },
-  { object: obj, type: 'update', val: 5 }
-]);
-
-// Accept
-reset();
-Object.observe(obj, observer.callback, ['somethingElse']);
-Object.getNotifier(obj).notify({
-  type: 'add'
-});
-Object.getNotifier(obj).notify({
-  type: 'update'
-});
-Object.getNotifier(obj).notify({
-  type: 'delete'
-});
-Object.getNotifier(obj).notify({
-  type: 'reconfigure'
-});
-Object.getNotifier(obj).notify({
-  type: 'setPrototype'
-});
-Object.deliverChangeRecords(observer.callback);
-observer.assertNotCalled();
-
-reset();
-Object.observe(obj, observer.callback, ['add', 'delete', 'setPrototype']);
-Object.getNotifier(obj).notify({
-  type: 'add'
-});
-Object.getNotifier(obj).notify({
-  type: 'update'
-});
-Object.getNotifier(obj).notify({
-  type: 'delete'
-});
-Object.getNotifier(obj).notify({
-  type: 'delete'
-});
-Object.getNotifier(obj).notify({
-  type: 'reconfigure'
-});
-Object.getNotifier(obj).notify({
-  type: 'setPrototype'
-});
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: obj, type: 'add' },
-  { object: obj, type: 'delete' },
-  { object: obj, type: 'delete' },
-  { object: obj, type: 'setPrototype' }
-]);
-
-reset();
-Object.observe(obj, observer.callback, ['update', 'foo']);
-Object.getNotifier(obj).notify({
-  type: 'add'
-});
-Object.getNotifier(obj).notify({
-  type: 'update'
-});
-Object.getNotifier(obj).notify({
-  type: 'delete'
-});
-Object.getNotifier(obj).notify({
-  type: 'foo'
-});
-Object.getNotifier(obj).notify({
-  type: 'bar'
-});
-Object.getNotifier(obj).notify({
-  type: 'foo'
-});
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: obj, type: 'update' },
-  { object: obj, type: 'foo' },
-  { object: obj, type: 'foo' }
-]);
-
-reset();
-function Thingy(a, b, c) {
-  this.a = a;
-  this.b = b;
-}
-
-Thingy.MULTIPLY = 'multiply';
-Thingy.INCREMENT = 'increment';
-Thingy.INCREMENT_AND_MULTIPLY = 'incrementAndMultiply';
-
-Thingy.prototype = {
-  increment: function(amount) {
-    var notifier = Object.getNotifier(this);
-
-    var self = this;
-    notifier.performChange(Thingy.INCREMENT, function() {
-      self.a += amount;
-      self.b += amount;
-
-      return {
-        incremented: amount
-      };  // implicit notify
-    });
-  },
-
-  multiply: function(amount) {
-    var notifier = Object.getNotifier(this);
-
-    var self = this;
-    notifier.performChange(Thingy.MULTIPLY, function() {
-      self.a *= amount;
-      self.b *= amount;
-
-      return {
-        multiplied: amount
-      };  // implicit notify
-    });
-  },
-
-  incrementAndMultiply: function(incAmount, multAmount) {
-    var notifier = Object.getNotifier(this);
-
-    var self = this;
-    notifier.performChange(Thingy.INCREMENT_AND_MULTIPLY, function() {
-      self.increment(incAmount);
-      self.multiply(multAmount);
-
-      return {
-        incremented: incAmount,
-        multiplied: multAmount
-      };  // implicit notify
-    });
-  }
-}
-
-Thingy.observe = function(thingy, callback) {
-  Object.observe(thingy, callback, [Thingy.INCREMENT,
-                                    Thingy.MULTIPLY,
-                                    Thingy.INCREMENT_AND_MULTIPLY,
-                                    'update']);
-}
-
-Thingy.unobserve = function(thingy, callback) {
-  Object.unobserve(thingy);
-}
-
-var thingy = new Thingy(2, 4);
-
-Object.observe(thingy, observer.callback);
-Thingy.observe(thingy, observer2.callback);
-thingy.increment(3);               // { a: 5, b: 7 }
-thingy.b++;                        // { a: 5, b: 8 }
-thingy.multiply(2);                // { a: 10, b: 16 }
-thingy.a++;                        // { a: 11, b: 16 }
-thingy.incrementAndMultiply(2, 2); // { a: 26, b: 36 }
-
-Object.deliverChangeRecords(observer.callback);
-Object.deliverChangeRecords(observer2.callback);
-observer.assertCallbackRecords([
-  { object: thingy, type: 'update', name: 'a', oldValue: 2 },
-  { object: thingy, type: 'update', name: 'b', oldValue: 4 },
-  { object: thingy, type: 'update', name: 'b', oldValue: 7 },
-  { object: thingy, type: 'update', name: 'a', oldValue: 5 },
-  { object: thingy, type: 'update', name: 'b', oldValue: 8 },
-  { object: thingy, type: 'update', name: 'a', oldValue: 10 },
-  { object: thingy, type: 'update', name: 'a', oldValue: 11 },
-  { object: thingy, type: 'update', name: 'b', oldValue: 16 },
-  { object: thingy, type: 'update', name: 'a', oldValue: 13 },
-  { object: thingy, type: 'update', name: 'b', oldValue: 18 },
-]);
-observer2.assertCallbackRecords([
-  { object: thingy, type: Thingy.INCREMENT, incremented: 3 },
-  { object: thingy, type: 'update', name: 'b', oldValue: 7 },
-  { object: thingy, type: Thingy.MULTIPLY, multiplied: 2 },
-  { object: thingy, type: 'update', name: 'a', oldValue: 10 },
-  {
-    object: thingy,
-    type: Thingy.INCREMENT_AND_MULTIPLY,
-    incremented: 2,
-    multiplied: 2
-  }
-]);
-
-// ArrayPush cached stub
-reset();
-
-function pushMultiple(arr) {
-  arr.push('a');
-  arr.push('b');
-  arr.push('c');
-}
-
-for (var i = 0; i < 5; i++) {
-  var arr = [];
-  pushMultiple(arr);
-}
-
-for (var i = 0; i < 5; i++) {
-  reset();
-  var arr = [];
-  Object.observe(arr, observer.callback);
-  pushMultiple(arr);
-  Object.unobserve(arr, observer.callback);
-  Object.deliverChangeRecords(observer.callback);
-  observer.assertCallbackRecords([
-    { object: arr, type: 'add', name: '0' },
-    { object: arr, type: 'update', name: 'length', oldValue: 0 },
-    { object: arr, type: 'add', name: '1' },
-    { object: arr, type: 'update', name: 'length', oldValue: 1 },
-    { object: arr, type: 'add', name: '2' },
-    { object: arr, type: 'update', name: 'length', oldValue: 2 },
-  ]);
-}
-
-
-// ArrayPop cached stub
-reset();
-
-function popMultiple(arr) {
-  arr.pop();
-  arr.pop();
-  arr.pop();
-}
-
-for (var i = 0; i < 5; i++) {
-  var arr = ['a', 'b', 'c'];
-  popMultiple(arr);
-}
-
-for (var i = 0; i < 5; i++) {
-  reset();
-  var arr = ['a', 'b', 'c'];
-  Object.observe(arr, observer.callback);
-  popMultiple(arr);
-  Object.unobserve(arr, observer.callback);
-  Object.deliverChangeRecords(observer.callback);
-  observer.assertCallbackRecords([
-    { object: arr, type: 'delete', name: '2', oldValue: 'c' },
-    { object: arr, type: 'update', name: 'length', oldValue: 3 },
-    { object: arr, type: 'delete', name: '1', oldValue: 'b' },
-    { object: arr, type: 'update', name: 'length', oldValue: 2 },
-    { object: arr, type: 'delete', name: '0', oldValue: 'a' },
-    { object: arr, type: 'update', name: 'length', oldValue: 1 },
-  ]);
-}
-
-
-reset();
-function RecursiveThingy() {}
-
-RecursiveThingy.MULTIPLY_FIRST_N = 'multiplyFirstN';
-
-RecursiveThingy.prototype = {
-  __proto__: Array.prototype,
-
-  multiplyFirstN: function(amount, n) {
-    if (!n)
-      return;
-    var notifier = Object.getNotifier(this);
-    var self = this;
-    notifier.performChange(RecursiveThingy.MULTIPLY_FIRST_N, function() {
-      self[n-1] = self[n-1]*amount;
-      self.multiplyFirstN(amount, n-1);
-    });
-
-    notifier.notify({
-      type: RecursiveThingy.MULTIPLY_FIRST_N,
-      multiplied: amount,
-      n: n
-    });
-  },
-}
-
-RecursiveThingy.observe = function(thingy, callback) {
-  Object.observe(thingy, callback, [RecursiveThingy.MULTIPLY_FIRST_N]);
-}
-
-RecursiveThingy.unobserve = function(thingy, callback) {
-  Object.unobserve(thingy);
-}
-
-var thingy = new RecursiveThingy;
-thingy.push(1, 2, 3, 4);
-
-Object.observe(thingy, observer.callback);
-RecursiveThingy.observe(thingy, observer2.callback);
-thingy.multiplyFirstN(2, 3);                // [2, 4, 6, 4]
-
-Object.deliverChangeRecords(observer.callback);
-Object.deliverChangeRecords(observer2.callback);
-observer.assertCallbackRecords([
-  { object: thingy, type: 'update', name: '2', oldValue: 3 },
-  { object: thingy, type: 'update', name: '1', oldValue: 2 },
-  { object: thingy, type: 'update', name: '0', oldValue: 1 }
-]);
-observer2.assertCallbackRecords([
-  { object: thingy, type: RecursiveThingy.MULTIPLY_FIRST_N, multiplied: 2, n: 3 }
-]);
-
-reset();
-function DeckSuit() {
-  this.push('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'A', 'Q', 'K');
-}
-
-DeckSuit.SHUFFLE = 'shuffle';
-
-DeckSuit.prototype = {
-  __proto__: Array.prototype,
-
-  shuffle: function() {
-    var notifier = Object.getNotifier(this);
-    var self = this;
-    notifier.performChange(DeckSuit.SHUFFLE, function() {
-      self.reverse();
-      self.sort(function() { return Math.random()* 2 - 1; });
-      var cut = self.splice(0, 6);
-      Array.prototype.push.apply(self, cut);
-      self.reverse();
-      self.sort(function() { return Math.random()* 2 - 1; });
-      var cut = self.splice(0, 6);
-      Array.prototype.push.apply(self, cut);
-      self.reverse();
-      self.sort(function() { return Math.random()* 2 - 1; });
-    });
-
-    notifier.notify({
-      type: DeckSuit.SHUFFLE
-    });
-  },
-}
-
-DeckSuit.observe = function(thingy, callback) {
-  Object.observe(thingy, callback, [DeckSuit.SHUFFLE]);
-}
-
-DeckSuit.unobserve = function(thingy, callback) {
-  Object.unobserve(thingy);
-}
-
-var deck = new DeckSuit;
-
-DeckSuit.observe(deck, observer2.callback);
-deck.shuffle();
-
-Object.deliverChangeRecords(observer2.callback);
-observer2.assertCallbackRecords([
-  { object: deck, type: DeckSuit.SHUFFLE }
-]);
-
-// Observing multiple objects; records appear in order.
-reset();
-var obj2 = {};
-var obj3 = {}
-Object.observe(obj, observer.callback);
-Object.observe(obj3, observer.callback);
-Object.observe(obj2, observer.callback);
-Object.getNotifier(obj).notify({
-  type: 'add',
-});
-Object.getNotifier(obj2).notify({
-  type: 'update',
-});
-Object.getNotifier(obj3).notify({
-  type: 'delete',
-});
-Object.observe(obj3, observer.callback);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: obj, type: 'add' },
-  { object: obj2, type: 'update' },
-  { object: obj3, type: 'delete' }
-]);
-
-
-// Recursive observation.
-var obj = {a: 1};
-var callbackCount = 0;
-function recursiveObserver(r) {
-  assertEquals(1, r.length);
-  ++callbackCount;
-  if (r[0].oldValue < 100) ++obj[r[0].name];
-}
-Object.observe(obj, recursiveObserver);
-++obj.a;
-Object.deliverChangeRecords(recursiveObserver);
-assertEquals(100, callbackCount);
-
-var obj1 = {a: 1};
-var obj2 = {a: 1};
-var recordCount = 0;
-function recursiveObserver2(r) {
-  recordCount += r.length;
-  if (r[0].oldValue < 100) {
-    ++obj1.a;
-    ++obj2.a;
-  }
-}
-Object.observe(obj1, recursiveObserver2);
-Object.observe(obj2, recursiveObserver2);
-++obj1.a;
-Object.deliverChangeRecords(recursiveObserver2);
-assertEquals(199, recordCount);
-
-
-// Observing named properties.
-reset();
-var obj = {a: 1}
-Object.observe(obj, observer.callback);
-obj.a = 2;
-obj["a"] = 3;
-delete obj.a;
-obj.a = 4;
-obj.a = 4;  // ignored
-obj.a = 5;
-Object.defineProperty(obj, "a", {value: 6});
-Object.defineProperty(obj, "a", {writable: false});
-obj.a = 7;  // ignored
-Object.defineProperty(obj, "a", {value: 8});
-Object.defineProperty(obj, "a", {value: 7, writable: true});
-Object.defineProperty(obj, "a", {get: function() {}});
-Object.defineProperty(obj, "a", {get: frozenFunction});
-Object.defineProperty(obj, "a", {get: frozenFunction});  // ignored
-Object.defineProperty(obj, "a", {get: frozenFunction, set: frozenFunction});
-Object.defineProperty(obj, "a", {set: frozenFunction});  // ignored
-Object.defineProperty(obj, "a", {get: undefined, set: frozenFunction});
-delete obj.a;
-delete obj.a;
-Object.defineProperty(obj, "a", {get: function() {}, configurable: true});
-Object.defineProperty(obj, "a", {value: 9, writable: true});
-obj.a = 10;
-++obj.a;
-obj.a++;
-obj.a *= 3;
-delete obj.a;
-Object.defineProperty(obj, "a", {value: 11, configurable: true});
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: obj, name: "a", type: "update", oldValue: 1 },
-  { object: obj, name: "a", type: "update", oldValue: 2 },
-  { object: obj, name: "a", type: "delete", oldValue: 3 },
-  { object: obj, name: "a", type: "add" },
-  { object: obj, name: "a", type: "update", oldValue: 4 },
-  { object: obj, name: "a", type: "update", oldValue: 5 },
-  { object: obj, name: "a", type: "reconfigure" },
-  { object: obj, name: "a", type: "update", oldValue: 6 },
-  { object: obj, name: "a", type: "reconfigure", oldValue: 8 },
-  { object: obj, name: "a", type: "reconfigure", oldValue: 7 },
-  { object: obj, name: "a", type: "reconfigure" },
-  { object: obj, name: "a", type: "reconfigure" },
-  { object: obj, name: "a", type: "reconfigure" },
-  { object: obj, name: "a", type: "delete" },
-  { object: obj, name: "a", type: "add" },
-  { object: obj, name: "a", type: "reconfigure" },
-  { object: obj, name: "a", type: "update", oldValue: 9 },
-  { object: obj, name: "a", type: "update", oldValue: 10 },
-  { object: obj, name: "a", type: "update", oldValue: 11 },
-  { object: obj, name: "a", type: "update", oldValue: 12 },
-  { object: obj, name: "a", type: "delete", oldValue: 36 },
-  { object: obj, name: "a", type: "add" },
-]);
-
-
-// Observing indexed properties.
-reset();
-var obj = {'1': 1}
-Object.observe(obj, observer.callback);
-obj[1] = 2;
-obj[1] = 3;
-delete obj[1];
-obj[1] = 4;
-obj[1] = 4;  // ignored
-obj[1] = 5;
-Object.defineProperty(obj, "1", {value: 6});
-Object.defineProperty(obj, "1", {writable: false});
-obj[1] = 7;  // ignored
-Object.defineProperty(obj, "1", {value: 8});
-Object.defineProperty(obj, "1", {value: 7, writable: true});
-Object.defineProperty(obj, "1", {get: function() {}});
-Object.defineProperty(obj, "1", {get: frozenFunction});
-Object.defineProperty(obj, "1", {get: frozenFunction});  // ignored
-Object.defineProperty(obj, "1", {get: frozenFunction, set: frozenFunction});
-Object.defineProperty(obj, "1", {set: frozenFunction});  // ignored
-Object.defineProperty(obj, "1", {get: undefined, set: frozenFunction});
-delete obj[1];
-delete obj[1];
-Object.defineProperty(obj, "1", {get: function() {}, configurable: true});
-Object.defineProperty(obj, "1", {value: 9, writable: true});
-obj[1] = 10;
-++obj[1];
-obj[1]++;
-obj[1] *= 3;
-delete obj[1];
-Object.defineProperty(obj, "1", {value: 11, configurable: true});
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: obj, name: "1", type: "update", oldValue: 1 },
-  { object: obj, name: "1", type: "update", oldValue: 2 },
-  { object: obj, name: "1", type: "delete", oldValue: 3 },
-  { object: obj, name: "1", type: "add" },
-  { object: obj, name: "1", type: "update", oldValue: 4 },
-  { object: obj, name: "1", type: "update", oldValue: 5 },
-  { object: obj, name: "1", type: "reconfigure" },
-  { object: obj, name: "1", type: "update", oldValue: 6 },
-  { object: obj, name: "1", type: "reconfigure", oldValue: 8 },
-  { object: obj, name: "1", type: "reconfigure", oldValue: 7 },
-  { object: obj, name: "1", type: "reconfigure" },
-  { object: obj, name: "1", type: "reconfigure" },
-  { object: obj, name: "1", type: "reconfigure" },
-  { object: obj, name: "1", type: "delete" },
-  { object: obj, name: "1", type: "add" },
-  { object: obj, name: "1", type: "reconfigure" },
-  { object: obj, name: "1", type: "update", oldValue: 9 },
-  { object: obj, name: "1", type: "update", oldValue: 10 },
-  { object: obj, name: "1", type: "update", oldValue: 11 },
-  { object: obj, name: "1", type: "update", oldValue: 12 },
-  { object: obj, name: "1", type: "delete", oldValue: 36 },
-  { object: obj, name: "1", type: "add" },
-]);
-
-
-// Observing symbol properties (not).
-print("*****")
-reset();
-var obj = {}
-var symbol = Symbol("secret");
-Object.observe(obj, observer.callback);
-obj[symbol] = 3;
-delete obj[symbol];
-Object.defineProperty(obj, symbol, {get: function() {}, configurable: true});
-Object.defineProperty(obj, symbol, {value: 6});
-Object.defineProperty(obj, symbol, {writable: false});
-delete obj[symbol];
-Object.defineProperty(obj, symbol, {value: 7});
-++obj[symbol];
-obj[symbol]++;
-obj[symbol] *= 3;
-delete obj[symbol];
-obj.__defineSetter__(symbol, function() {});
-obj.__defineGetter__(symbol, function() {});
-Object.deliverChangeRecords(observer.callback);
-observer.assertNotCalled();
-
-
-// Test all kinds of objects generically.
-function TestObserveConfigurable(obj, prop) {
-  reset();
-  Object.observe(obj, observer.callback);
-  Object.unobserve(obj, observer.callback);
-  obj[prop] = 1;
-  Object.observe(obj, observer.callback);
-  obj[prop] = 2;
-  obj[prop] = 3;
-  delete obj[prop];
-  obj[prop] = 4;
-  obj[prop] = 4;  // ignored
-  obj[prop] = 5;
-  Object.defineProperty(obj, prop, {value: 6});
-  Object.defineProperty(obj, prop, {writable: false});
-  obj[prop] = 7;  // ignored
-  Object.defineProperty(obj, prop, {value: 8});
-  Object.defineProperty(obj, prop, {value: 7, writable: true});
-  Object.defineProperty(obj, prop, {get: function() {}});
-  Object.defineProperty(obj, prop, {get: frozenFunction});
-  Object.defineProperty(obj, prop, {get: frozenFunction});  // ignored
-  Object.defineProperty(obj, prop, {get: frozenFunction, set: frozenFunction});
-  Object.defineProperty(obj, prop, {set: frozenFunction});  // ignored
-  Object.defineProperty(obj, prop, {get: undefined, set: frozenFunction});
-  obj.__defineSetter__(prop, frozenFunction);  // ignored
-  obj.__defineSetter__(prop, function() {});
-  obj.__defineGetter__(prop, function() {});
-  delete obj[prop];
-  delete obj[prop];  // ignored
-  obj.__defineGetter__(prop, function() {});
-  delete obj[prop];
-  Object.defineProperty(obj, prop, {get: function() {}, configurable: true});
-  Object.defineProperty(obj, prop, {value: 9, writable: true});
-  obj[prop] = 10;
-  ++obj[prop];
-  obj[prop]++;
-  obj[prop] *= 3;
-  delete obj[prop];
-  Object.defineProperty(obj, prop, {value: 11, configurable: true});
-  Object.deliverChangeRecords(observer.callback);
-  observer.assertCallbackRecords([
-    { object: obj, name: prop, type: "update", oldValue: 1 },
-    { object: obj, name: prop, type: "update", oldValue: 2 },
-    { object: obj, name: prop, type: "delete", oldValue: 3 },
-    { object: obj, name: prop, type: "add" },
-    { object: obj, name: prop, type: "update", oldValue: 4 },
-    { object: obj, name: prop, type: "update", oldValue: 5 },
-    { object: obj, name: prop, type: "reconfigure" },
-    { object: obj, name: prop, type: "update", oldValue: 6 },
-    { object: obj, name: prop, type: "reconfigure", oldValue: 8 },
-    { object: obj, name: prop, type: "reconfigure", oldValue: 7 },
-    { object: obj, name: prop, type: "reconfigure" },
-    { object: obj, name: prop, type: "reconfigure" },
-    { object: obj, name: prop, type: "reconfigure" },
-    { object: obj, name: prop, type: "reconfigure" },
-    { object: obj, name: prop, type: "reconfigure" },
-    { object: obj, name: prop, type: "delete" },
-    { object: obj, name: prop, type: "add" },
-    { object: obj, name: prop, type: "delete" },
-    { object: obj, name: prop, type: "add" },
-    { object: obj, name: prop, type: "reconfigure" },
-    { object: obj, name: prop, type: "update", oldValue: 9 },
-    { object: obj, name: prop, type: "update", oldValue: 10 },
-    { object: obj, name: prop, type: "update", oldValue: 11 },
-    { object: obj, name: prop, type: "update", oldValue: 12 },
-    { object: obj, name: prop, type: "delete", oldValue: 36 },
-    { object: obj, name: prop, type: "add" },
-  ]);
-  Object.unobserve(obj, observer.callback);
-  delete obj[prop];
-}
-
-function TestObserveNonConfigurable(obj, prop, desc) {
-  reset();
-  Object.observe(obj, observer.callback);
-  Object.unobserve(obj, observer.callback);
-  obj[prop] = 1;
-  Object.observe(obj, observer.callback);
-  obj[prop] = 4;
-  obj[prop] = 4;  // ignored
-  obj[prop] = 5;
-  Object.defineProperty(obj, prop, {value: 6});
-  Object.defineProperty(obj, prop, {value: 6});  // ignored
-  Object.defineProperty(obj, prop, {value: 7});
-  Object.defineProperty(obj, prop, {enumerable: desc.enumerable});  // ignored
-  Object.defineProperty(obj, prop, {writable: false});
-  obj[prop] = 7;  // ignored
-  Object.deliverChangeRecords(observer.callback);
-  observer.assertCallbackRecords([
-    { object: obj, name: prop, type: "update", oldValue: 1 },
-    { object: obj, name: prop, type: "update", oldValue: 4 },
-    { object: obj, name: prop, type: "update", oldValue: 5 },
-    { object: obj, name: prop, type: "update", oldValue: 6 },
-    { object: obj, name: prop, type: "reconfigure" },
-  ]);
-  Object.unobserve(obj, observer.callback);
-}
-
-// TODO(rafaelw) Enable when ES6 Proxies are implemented
-/*
-function createProxy(create, x) {
-  var handler = {
-    getPropertyDescriptor: function(k) {
-      for (var o = this.target; o; o = Object.getPrototypeOf(o)) {
-        var desc = Object.getOwnPropertyDescriptor(o, k);
-        if (desc) return desc;
-      }
-      return undefined;
-    },
-    getOwnPropertyDescriptor: function(k) {
-      return Object.getOwnPropertyDescriptor(this.target, k);
-    },
-    defineProperty: function(k, desc) {
-      var x = Object.defineProperty(this.target, k, desc);
-      Object.deliverChangeRecords(this.callback);
-      return x;
-    },
-    delete: function(k) {
-      var x = delete this.target[k];
-      Object.deliverChangeRecords(this.callback);
-      return x;
-    },
-    getPropertyNames: function() {
-      return Object.getOwnPropertyNames(this.target);
-    },
-    target: {isProxy: true},
-    callback: function(changeRecords) {
-      print("callback", stringifyNoThrow(handler.proxy), stringifyNoThrow(got));
-      for (var i in changeRecords) {
-        var got = changeRecords[i];
-        var change = {object: handler.proxy, name: got.name, type: got.type};
-        if ("oldValue" in got) change.oldValue = got.oldValue;
-        Object.getNotifier(handler.proxy).notify(change);
-      }
-    },
-  };
-  Object.observe(handler.target, handler.callback);
-  return handler.proxy = create(handler, x);
-}
-*/
-
-var objects = [
-  {},
-  [],
-  function(){},
-  (function(){ return arguments })(),
-  (function(){ "use strict"; return arguments })(),
-  Object(1), Object(true), Object("bla"),
-  new Date(),
-  Object, Function, Date, RegExp,
-  new Set, new Map, new WeakMap,
-  new ArrayBuffer(10), new Int32Array(5)
-// TODO(rafaelw) Enable when ES6 Proxies are implemented.
-//  createProxy(Proxy.create, null),
-//  createProxy(Proxy.createFunction, function(){}),
-];
-var properties = ["a", "1", 1, "length", "setPrototype", "name", "caller"];
-
-// Cases that yield non-standard results.
-function blacklisted(obj, prop) {
-  return (obj instanceof Int32Array && prop == 1) ||
-         (obj instanceof Int32Array && prop === "length") ||
-         (obj instanceof ArrayBuffer && prop == 1) ||
-         (obj instanceof Function && prop === "name") ||  // Has its own test.
-         (obj instanceof Function && prop === "length");  // Has its own test.
-}
-
-for (var i in objects) for (var j in properties) {
-  var obj = objects[i];
-  var prop = properties[j];
-  if (blacklisted(obj, prop)) continue;
-  var desc = Object.getOwnPropertyDescriptor(obj, prop);
-  print("***", typeof obj, stringifyNoThrow(obj), prop);
-  if (!desc || desc.configurable)
-    TestObserveConfigurable(obj, prop);
-  else if (desc.writable)
-    TestObserveNonConfigurable(obj, prop, desc);
-}
-
-
-// Observing array length (including truncation)
-reset();
-var arr = ['a', 'b', 'c', 'd'];
-var arr2 = ['alpha', 'beta'];
-var arr3 = ['hello'];
-arr3[2] = 'goodbye';
-arr3.length = 6;
-Object.defineProperty(arr, '0', {configurable: false});
-Object.defineProperty(arr, '2', {get: function(){}});
-Object.defineProperty(arr2, '0', {get: function(){}, configurable: false});
-Object.observe(arr, observer.callback);
-Array.observe(arr, observer2.callback);
-Object.observe(arr2, observer.callback);
-Array.observe(arr2, observer2.callback);
-Object.observe(arr3, observer.callback);
-Array.observe(arr3, observer2.callback);
-arr.length = 2;
-arr.length = 0;
-arr.length = 10;
-Object.defineProperty(arr, 'length', {writable: false});
-arr2.length = 0;
-arr2.length = 1; // no change expected
-Object.defineProperty(arr2, 'length', {value: 1, writable: false});
-arr3.length = 0;
-++arr3.length;
-arr3.length++;
-arr3.length /= 2;
-Object.defineProperty(arr3, 'length', {value: 5});
-arr3[4] = 5;
-Object.defineProperty(arr3, 'length', {value: 1, writable: false});
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: arr, name: '3', type: 'delete', oldValue: 'd' },
-  { object: arr, name: '2', type: 'delete' },
-  { object: arr, name: 'length', type: 'update', oldValue: 4 },
-  { object: arr, name: '1', type: 'delete', oldValue: 'b' },
-  { object: arr, name: 'length', type: 'update', oldValue: 2 },
-  { object: arr, name: 'length', type: 'update', oldValue: 1 },
-  { object: arr, name: 'length', type: 'reconfigure' },
-  { object: arr2, name: '1', type: 'delete', oldValue: 'beta' },
-  { object: arr2, name: 'length', type: 'update', oldValue: 2 },
-  { object: arr2, name: 'length', type: 'reconfigure' },
-  { object: arr3, name: '2', type: 'delete', oldValue: 'goodbye' },
-  { object: arr3, name: '0', type: 'delete', oldValue: 'hello' },
-  { object: arr3, name: 'length', type: 'update', oldValue: 6 },
-  { object: arr3, name: 'length', type: 'update', oldValue: 0 },
-  { object: arr3, name: 'length', type: 'update', oldValue: 1 },
-  { object: arr3, name: 'length', type: 'update', oldValue: 2 },
-  { object: arr3, name: 'length', type: 'update', oldValue: 1 },
-  { object: arr3, name: '4', type: 'add' },
-  { object: arr3, name: '4', type: 'delete', oldValue: 5 },
-  // TODO(rafaelw): It breaks spec compliance to get two records here.
-  // When the TODO in v8natives.js::DefineArrayProperty is addressed
-  // which prevents DefineProperty from over-writing the magic length
-  // property, these will collapse into a single record.
-  { object: arr3, name: 'length', type: 'update', oldValue: 5 },
-  { object: arr3, name: 'length', type: 'reconfigure' }
-]);
-Object.deliverChangeRecords(observer2.callback);
-observer2.assertCallbackRecords([
-  { object: arr, type: 'splice', index: 2, removed: [, 'd'], addedCount: 0 },
-  { object: arr, type: 'splice', index: 1, removed: ['b'], addedCount: 0 },
-  { object: arr, type: 'splice', index: 1, removed: [], addedCount: 9 },
-  { object: arr2, type: 'splice', index: 1, removed: ['beta'], addedCount: 0 },
-  { object: arr3, type: 'splice', index: 0, removed: ['hello',, 'goodbye',,,,], addedCount: 0 },
-  { object: arr3, type: 'splice', index: 0, removed: [], addedCount: 1 },
-  { object: arr3, type: 'splice', index: 1, removed: [], addedCount: 1 },
-  { object: arr3, type: 'splice', index: 1, removed: [,], addedCount: 0 },
-  { object: arr3, type: 'splice', index: 1, removed: [], addedCount: 4 },
-  { object: arr3, name: '4', type: 'add' },
-  { object: arr3, type: 'splice', index: 1, removed: [,,,5], addedCount: 0 }
-]);
-
-
-// Updating length on large (slow) array
-reset();
-var slow_arr = %NormalizeElements([]);
-slow_arr[500000000] = 'hello';
-slow_arr.length = 1000000000;
-Object.observe(slow_arr, observer.callback);
-var spliceRecords;
-function slowSpliceCallback(records) {
-  spliceRecords = records;
-}
-Array.observe(slow_arr, slowSpliceCallback);
-slow_arr.length = 100;
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: slow_arr, name: '500000000', type: 'delete', oldValue: 'hello' },
-  { object: slow_arr, name: 'length', type: 'update', oldValue: 1000000000 },
-]);
-Object.deliverChangeRecords(slowSpliceCallback);
-assertEquals(spliceRecords.length, 1);
-// Have to custom assert this splice record because the removed array is huge.
-var splice = spliceRecords[0];
-assertSame(splice.object, slow_arr);
-assertEquals(splice.type, 'splice');
-assertEquals(splice.index, 100);
-assertEquals(splice.addedCount, 0);
-var array_keys = %GetArrayKeys(splice.removed, splice.removed.length);
-assertEquals(array_keys.length, 1);
-assertEquals(array_keys[0], 499999900);
-assertEquals(splice.removed[499999900], 'hello');
-assertEquals(splice.removed.length, 999999900);
-
-
-// Assignments in loops (checking different IC states).
-reset();
-var obj = {};
-Object.observe(obj, observer.callback);
-for (var i = 0; i < 5; i++) {
-  obj["a" + i] = i;
-}
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: obj, name: "a0", type: "add" },
-  { object: obj, name: "a1", type: "add" },
-  { object: obj, name: "a2", type: "add" },
-  { object: obj, name: "a3", type: "add" },
-  { object: obj, name: "a4", type: "add" },
-]);
-
-reset();
-var obj = {};
-Object.observe(obj, observer.callback);
-for (var i = 0; i < 5; i++) {
-  obj[i] = i;
-}
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: obj, name: "0", type: "add" },
-  { object: obj, name: "1", type: "add" },
-  { object: obj, name: "2", type: "add" },
-  { object: obj, name: "3", type: "add" },
-  { object: obj, name: "4", type: "add" },
-]);
-
-
-// Adding elements past the end of an array should notify on length for
-// Object.observe and emit "splices" for Array.observe.
-reset();
-var arr = [1, 2, 3];
-Object.observe(arr, observer.callback);
-Array.observe(arr, observer2.callback);
-arr[3] = 10;
-arr[100] = 20;
-Object.defineProperty(arr, '200', {value: 7});
-Object.defineProperty(arr, '400', {get: function(){}});
-arr[50] = 30; // no length change expected
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: arr, name: '3', type: 'add' },
-  { object: arr, name: 'length', type: 'update', oldValue: 3 },
-  { object: arr, name: '100', type: 'add' },
-  { object: arr, name: 'length', type: 'update', oldValue: 4 },
-  { object: arr, name: '200', type: 'add' },
-  { object: arr, name: 'length', type: 'update', oldValue: 101 },
-  { object: arr, name: '400', type: 'add' },
-  { object: arr, name: 'length', type: 'update', oldValue: 201 },
-  { object: arr, name: '50', type: 'add' },
-]);
-Object.deliverChangeRecords(observer2.callback);
-observer2.assertCallbackRecords([
-  { object: arr, type: 'splice', index: 3, removed: [], addedCount: 1 },
-  { object: arr, type: 'splice', index: 4, removed: [], addedCount: 97 },
-  { object: arr, type: 'splice', index: 101, removed: [], addedCount: 100 },
-  { object: arr, type: 'splice', index: 201, removed: [], addedCount: 200 },
-  { object: arr, type: 'add', name: '50' },
-]);
-
-
-// Tests for array methods, first on arrays and then on plain objects
-//
-// === ARRAYS ===
-//
-// Push
-reset();
-var array = [1, 2];
-Object.observe(array, observer.callback);
-Array.observe(array, observer2.callback);
-array.push(3, 4);
-array.push(5);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: array, name: '2', type: 'add' },
-  { object: array, name: 'length', type: 'update', oldValue: 2 },
-  { object: array, name: '3', type: 'add' },
-  { object: array, name: 'length', type: 'update', oldValue: 3 },
-  { object: array, name: '4', type: 'add' },
-  { object: array, name: 'length', type: 'update', oldValue: 4 },
-]);
-Object.deliverChangeRecords(observer2.callback);
-observer2.assertCallbackRecords([
-  { object: array, type: 'splice', index: 2, removed: [], addedCount: 2 },
-  { object: array, type: 'splice', index: 4, removed: [], addedCount: 1 }
-]);
-
-// Pop
-reset();
-var array = [1, 2];
-Object.observe(array, observer.callback);
-array.pop();
-array.pop();
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: array, name: '1', type: 'delete', oldValue: 2 },
-  { object: array, name: 'length', type: 'update', oldValue: 2 },
-  { object: array, name: '0', type: 'delete', oldValue: 1 },
-  { object: array, name: 'length', type: 'update', oldValue: 1 },
-]);
-
-// Shift
-reset();
-var array = [1, 2];
-Object.observe(array, observer.callback);
-array.shift();
-array.shift();
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: array, name: '0', type: 'update', oldValue: 1 },
-  { object: array, name: '1', type: 'delete', oldValue: 2 },
-  { object: array, name: 'length', type: 'update', oldValue: 2 },
-  { object: array, name: '0', type: 'delete', oldValue: 2 },
-  { object: array, name: 'length', type: 'update', oldValue: 1 },
-]);
-
-// Unshift
-reset();
-var array = [1, 2];
-Object.observe(array, observer.callback);
-array.unshift(3, 4);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: array, name: '3', type: 'add' },
-  { object: array, name: 'length', type: 'update', oldValue: 2 },
-  { object: array, name: '2', type: 'add' },
-  { object: array, name: '0', type: 'update', oldValue: 1 },
-  { object: array, name: '1', type: 'update', oldValue: 2 },
-]);
-
-// Splice
-reset();
-var array = [1, 2, 3];
-Object.observe(array, observer.callback);
-array.splice(1, 1, 4, 5);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: array, name: '3', type: 'add' },
-  { object: array, name: 'length', type: 'update', oldValue: 3 },
-  { object: array, name: '1', type: 'update', oldValue: 2 },
-  { object: array, name: '2', type: 'update', oldValue: 3 },
-]);
-
-// Sort
-reset();
-var array = [3, 2, 1];
-Object.observe(array, observer.callback);
-array.sort();
-assertEquals(1, array[0]);
-assertEquals(2, array[1]);
-assertEquals(3, array[2]);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: array, name: '1', type: 'update', oldValue: 2 },
-  { object: array, name: '0', type: 'update', oldValue: 3 },
-  { object: array, name: '2', type: 'update', oldValue: 1 },
-  { object: array, name: '1', type: 'update', oldValue: 3 },
-  { object: array, name: '0', type: 'update', oldValue: 2 },
-]);
-
-// Splice emitted after Array mutation methods
-function MockArray(initial, observer) {
-  for (var i = 0; i < initial.length; i++)
-    this[i] = initial[i];
-
-  this.length_ = initial.length;
-  this.observer = observer;
-}
-MockArray.prototype = {
-  set length(length) {
-    Object.getNotifier(this).notify({ type: 'lengthChange' });
-    this.length_ = length;
-    Object.observe(this, this.observer.callback, ['splice']);
-  },
-  get length() {
-    return this.length_;
-  }
-}
-
-reset();
-var array = new MockArray([], observer);
-Object.observe(array, observer.callback, ['lengthChange']);
-Array.prototype.push.call(array, 1);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: array, type: 'lengthChange' },
-  { object: array, type: 'splice', index: 0, removed: [], addedCount: 1 },
-]);
-
-reset();
-var array = new MockArray([1], observer);
-Object.observe(array, observer.callback, ['lengthChange']);
-Array.prototype.pop.call(array);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: array, type: 'lengthChange' },
-  { object: array, type: 'splice', index: 0, removed: [1], addedCount: 0 },
-]);
-
-reset();
-var array = new MockArray([1], observer);
-Object.observe(array, observer.callback, ['lengthChange']);
-Array.prototype.shift.call(array);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: array, type: 'lengthChange' },
-  { object: array, type: 'splice', index: 0, removed: [1], addedCount: 0 },
-]);
-
-reset();
-var array = new MockArray([], observer);
-Object.observe(array, observer.callback, ['lengthChange']);
-Array.prototype.unshift.call(array, 1);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: array, type: 'lengthChange' },
-  { object: array, type: 'splice', index: 0, removed: [], addedCount: 1 },
-]);
-
-reset();
-var array = new MockArray([0, 1, 2], observer);
-Object.observe(array, observer.callback, ['lengthChange']);
-Array.prototype.splice.call(array, 1, 1);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: array, type: 'lengthChange' },
-  { object: array, type: 'splice', index: 1, removed: [1], addedCount: 0 },
-]);
-
-//
-// === PLAIN OBJECTS ===
-//
-// Push
-reset()
-var array = {0: 1, 1: 2, length: 2}
-Object.observe(array, observer.callback);
-Array.prototype.push.call(array, 3, 4);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: array, name: '2', type: 'add' },
-  { object: array, name: '3', type: 'add' },
-  { object: array, name: 'length', type: 'update', oldValue: 2 },
-]);
-
-// Pop
-reset();
-var array = [1, 2];
-Object.observe(array, observer.callback);
-Array.observe(array, observer2.callback);
-array.pop();
-array.pop();
-array.pop();
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: array, name: '1', type: 'delete', oldValue: 2 },
-  { object: array, name: 'length', type: 'update', oldValue: 2 },
-  { object: array, name: '0', type: 'delete', oldValue: 1 },
-  { object: array, name: 'length', type: 'update', oldValue: 1 },
-]);
-Object.deliverChangeRecords(observer2.callback);
-observer2.assertCallbackRecords([
-  { object: array, type: 'splice', index: 1, removed: [2], addedCount: 0 },
-  { object: array, type: 'splice', index: 0, removed: [1], addedCount: 0 }
-]);
-
-// Shift
-reset();
-var array = [1, 2];
-Object.observe(array, observer.callback);
-Array.observe(array, observer2.callback);
-array.shift();
-array.shift();
-array.shift();
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: array, name: '0', type: 'update', oldValue: 1 },
-  { object: array, name: '1', type: 'delete', oldValue: 2 },
-  { object: array, name: 'length', type: 'update', oldValue: 2 },
-  { object: array, name: '0', type: 'delete', oldValue: 2 },
-  { object: array, name: 'length', type: 'update', oldValue: 1 },
-]);
-Object.deliverChangeRecords(observer2.callback);
-observer2.assertCallbackRecords([
-  { object: array, type: 'splice', index: 0, removed: [1], addedCount: 0 },
-  { object: array, type: 'splice', index: 0, removed: [2], addedCount: 0 }
-]);
-
-// Unshift
-reset();
-var array = [1, 2];
-Object.observe(array, observer.callback);
-Array.observe(array, observer2.callback);
-array.unshift(3, 4);
-array.unshift(5);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: array, name: '3', type: 'add' },
-  { object: array, name: 'length', type: 'update', oldValue: 2 },
-  { object: array, name: '2', type: 'add' },
-  { object: array, name: '0', type: 'update', oldValue: 1 },
-  { object: array, name: '1', type: 'update', oldValue: 2 },
-  { object: array, name: '4', type: 'add' },
-  { object: array, name: 'length', type: 'update', oldValue: 4 },
-  { object: array, name: '3', type: 'update', oldValue: 2 },
-  { object: array, name: '2', type: 'update', oldValue: 1 },
-  { object: array, name: '1', type: 'update', oldValue: 4 },
-  { object: array, name: '0', type: 'update', oldValue: 3 },
-]);
-Object.deliverChangeRecords(observer2.callback);
-observer2.assertCallbackRecords([
-  { object: array, type: 'splice', index: 0, removed: [], addedCount: 2 },
-  { object: array, type: 'splice', index: 0, removed: [], addedCount: 1 }
-]);
-
-// Splice
-reset();
-var array = [1, 2, 3];
-Object.observe(array, observer.callback);
-Array.observe(array, observer2.callback);
-array.splice(1, 0, 4, 5); // 1 4 5 2 3
-array.splice(0, 2); // 5 2 3
-array.splice(1, 2, 6, 7); // 5 6 7
-array.splice(2, 0);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: array, name: '4', type: 'add' },
-  { object: array, name: 'length', type: 'update', oldValue: 3 },
-  { object: array, name: '3', type: 'add' },
-  { object: array, name: '1', type: 'update', oldValue: 2 },
-  { object: array, name: '2', type: 'update', oldValue: 3 },
-
-  { object: array, name: '0', type: 'update', oldValue: 1 },
-  { object: array, name: '1', type: 'update', oldValue: 4 },
-  { object: array, name: '2', type: 'update', oldValue: 5 },
-  { object: array, name: '4', type: 'delete', oldValue: 3 },
-  { object: array, name: '3', type: 'delete', oldValue: 2 },
-  { object: array, name: 'length', type: 'update', oldValue: 5 },
-
-  { object: array, name: '1', type: 'update', oldValue: 2 },
-  { object: array, name: '2', type: 'update', oldValue: 3 },
-]);
-Object.deliverChangeRecords(observer2.callback);
-observer2.assertCallbackRecords([
-  { object: array, type: 'splice', index: 1, removed: [], addedCount: 2 },
-  { object: array, type: 'splice', index: 0, removed: [1, 4], addedCount: 0 },
-  { object: array, type: 'splice', index: 1, removed: [2, 3], addedCount: 2 },
-]);
-
-// Exercise StoreIC_ArrayLength
-reset();
-var dummy = {};
-Object.observe(dummy, observer.callback);
-Object.unobserve(dummy, observer.callback);
-var array = [0];
-Object.observe(array, observer.callback);
-array.splice(0, 1);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: array, name: '0', type: 'delete', oldValue: 0 },
-  { object: array, name: 'length', type: 'update', oldValue: 1},
-]);
-
-
-// __proto__
-reset();
-var obj = {};
-Object.observe(obj, observer.callback);
-var p = {foo: 'yes'};
-var q = {bar: 'no'};
-obj.__proto__ = p;
-obj.__proto__ = p;  // ignored
-obj.__proto__ = null;
-obj.__proto__ = q;  // the __proto__ accessor is gone
-// TODO(adamk): Add tests for objects with hidden prototypes
-// once we support observing the global object.
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: obj, name: '__proto__', type: 'setPrototype',
-    oldValue: Object.prototype },
-  { object: obj, name: '__proto__', type: 'setPrototype', oldValue: p },
-  { object: obj, name: '__proto__', type: 'add' },
-]);
-
-
-// Function.prototype
-reset();
-var fun = function(){};
-Object.observe(fun, observer.callback);
-var myproto = {foo: 'bar'};
-fun.prototype = myproto;
-fun.prototype = 7;
-fun.prototype = 7;  // ignored
-Object.defineProperty(fun, 'prototype', {value: 8});
-Object.deliverChangeRecords(observer.callback);
-observer.assertRecordCount(3);
-// Manually examine the first record in order to test
-// lazy creation of oldValue
-assertSame(fun, observer.records[0].object);
-assertEquals('prototype', observer.records[0].name);
-assertEquals('update', observer.records[0].type);
-// The only existing reference to the oldValue object is in this
-// record, so to test that lazy creation happened correctly
-// we compare its constructor to our function (one of the invariants
-// ensured when creating an object via AllocateFunctionPrototype).
-assertSame(fun, observer.records[0].oldValue.constructor);
-observer.records.splice(0, 1);
-observer.assertCallbackRecords([
-  { object: fun, name: 'prototype', type: 'update', oldValue: myproto },
-  { object: fun, name: 'prototype', type: 'update', oldValue: 7 },
-]);
-
-// Function.prototype should not be observable except on the object itself
-reset();
-var fun = function(){};
-var obj = { __proto__: fun };
-Object.observe(obj, observer.callback);
-obj.prototype = 7;
-Object.deliverChangeRecords(observer.callback);
-observer.assertRecordCount(1);
-observer.assertCallbackRecords([
-  { object: obj, name: 'prototype', type: 'add' },
-]);
-
-// Check that changes in observation status are detected in all IC states and
-// in optimized code, especially in cases usually using fast elements.
-var mutation = [
-  "a[i] = v",
-  "a[i] ? ++a[i] : a[i] = v",
-  "a[i] ? a[i]++ : a[i] = v",
-  "a[i] ? a[i] += 1 : a[i] = v",
-  "a[i] ? a[i] -= -1 : a[i] = v",
-];
-
-var props = [1, "1", "a"];
-
-function TestFastElements(prop, mutation, prepopulate, polymorphic, optimize) {
-  var setElement = eval(
-    "(function setElement(a, i, v) { " + mutation + "; " +
-    "/* " + [].join.call(arguments, " ") + " */" +
-    "})"
-  );
-  print("TestFastElements:", setElement);
-
-  var arr = prepopulate ? [1, 2, 3, 4, 5] : [0];
-  if (prepopulate) arr[prop] = 2;  // for non-element case
-  setElement(arr, prop, 3);
-  setElement(arr, prop, 4);
-  if (polymorphic) setElement(["M", "i", "l", "n", "e", "r"], 0, "m");
-  if (optimize) %OptimizeFunctionOnNextCall(setElement);
-  setElement(arr, prop, 5);
-
-  reset();
-  Object.observe(arr, observer.callback);
-  setElement(arr, prop, 989898);
-  Object.deliverChangeRecords(observer.callback);
-  observer.assertCallbackRecords([
-    { object: arr, name: "" + prop, type: 'update', oldValue: 5 }
-  ]);
-}
-
-for (var b1 = 0; b1 < 2; ++b1)
-  for (var b2 = 0; b2 < 2; ++b2)
-    for (var b3 = 0; b3 < 2; ++b3)
-      for (var i in props)
-        for (var j in mutation)
-          TestFastElements(props[i], mutation[j], b1 != 0, b2 != 0, b3 != 0);
-
-
-var mutation = [
-  "a.length = v",
-  "a.length += newSize - oldSize",
-  "a.length -= oldSize - newSize",
-];
-
-var mutationByIncr = [
-  "++a.length",
-  "a.length++",
-];
-
-function TestFastElementsLength(
-  mutation, polymorphic, optimize, oldSize, newSize) {
-  var setLength = eval(
-    "(function setLength(a, v) { " + mutation + "; " +
-    "/* " + [].join.call(arguments, " ") + " */"
-    + "})"
-  );
-  print("TestFastElementsLength:", setLength);
-
-  function array(n) {
-    var arr = new Array(n);
-    for (var i = 0; i < n; ++i) arr[i] = i;
-    return arr;
-  }
-
-  setLength(array(oldSize), newSize);
-  setLength(array(oldSize), newSize);
-  if (polymorphic) setLength(array(oldSize).map(isNaN), newSize);
-  if (optimize) %OptimizeFunctionOnNextCall(setLength);
-  setLength(array(oldSize), newSize);
-
-  reset();
-  var arr = array(oldSize);
-  Object.observe(arr, observer.callback);
-  setLength(arr, newSize);
-  Object.deliverChangeRecords(observer.callback);
-  if (oldSize === newSize) {
-    observer.assertNotCalled();
-  } else {
-    var count = oldSize > newSize ? oldSize - newSize : 0;
-    observer.assertRecordCount(count + 1);
-    var lengthRecord = observer.records[count];
-    assertSame(arr, lengthRecord.object);
-    assertEquals('length', lengthRecord.name);
-    assertEquals('update', lengthRecord.type);
-    assertSame(oldSize, lengthRecord.oldValue);
-  }
-}
-
-for (var b1 = 0; b1 < 2; ++b1)
-  for (var b2 = 0; b2 < 2; ++b2)
-    for (var n1 = 0; n1 < 3; ++n1)
-      for (var n2 = 0; n2 < 3; ++n2)
-        for (var i in mutation)
-          TestFastElementsLength(mutation[i], b1 != 0, b2 != 0, 20*n1, 20*n2);
-
-for (var b1 = 0; b1 < 2; ++b1)
-  for (var b2 = 0; b2 < 2; ++b2)
-    for (var n = 0; n < 3; ++n)
-      for (var i in mutationByIncr)
-        TestFastElementsLength(mutationByIncr[i], b1 != 0, b2 != 0, 7*n, 7*n+1);
-
-
-(function TestFunctionName() {
-  reset();
-
-  function fun() {}
-  Object.observe(fun, observer.callback);
-  fun.name = 'x';  // No change. Not writable.
-  Object.defineProperty(fun, 'name', {value: 'a'});
-  Object.defineProperty(fun, 'name', {writable: true});
-  fun.name = 'b';
-  delete fun.name;
-  fun.name = 'x';  // No change. Function.prototype.name is non writable
-  Object.defineProperty(Function.prototype, 'name', {writable: true});
-  fun.name = 'c';
-  fun.name = 'c';  // Same, no update.
-  Object.deliverChangeRecords(observer.callback);
-  observer.assertCallbackRecords([
-    { object: fun, type: 'update', name: 'name', oldValue: 'fun' },
-    { object: fun, type: 'reconfigure', name: 'name'},
-    { object: fun, type: 'update', name: 'name', oldValue: 'a' },
-    { object: fun, type: 'delete', name: 'name', oldValue: 'b' },
-    { object: fun, type: 'add', name: 'name' },
-  ]);
-})();
-
-
-(function TestFunctionLength() {
-  reset();
-
-  function fun(x) {}
-  Object.observe(fun, observer.callback);
-  fun.length = 'x';  // No change. Not writable.
-  Object.defineProperty(fun, 'length', {value: 'a'});
-  Object.defineProperty(fun, 'length', {writable: true});
-  fun.length = 'b';
-  delete fun.length;
-  fun.length = 'x';  // No change. Function.prototype.length is non writable
-  Object.defineProperty(Function.prototype, 'length', {writable: true});
-  fun.length = 'c';
-  fun.length = 'c';  // Same, no update.
-  Object.deliverChangeRecords(observer.callback);
-  observer.assertCallbackRecords([
-    { object: fun, type: 'update', name: 'length', oldValue: 1 },
-    { object: fun, type: 'reconfigure', name: 'length'},
-    { object: fun, type: 'update', name: 'length', oldValue: 'a' },
-    { object: fun, type: 'delete', name: 'length', oldValue: 'b' },
-    { object: fun, type: 'add', name: 'length' },
-  ]);
-})();
-
-
-(function TestObserveInvalidAcceptMessage() {
-  var ex;
-  try {
-    Object.observe({}, function(){}, "not an object");
-  } catch (e) {
-    ex = e;
-  }
-  assertInstanceof(ex, TypeError);
-  assertEquals("Third argument to Object.observe must be an array of strings.",
-               ex.message);
-})()
diff --git a/test/mjsunit/es7/regress/regress-443982.js b/test/mjsunit/es7/regress/regress-443982.js
deleted file mode 100644
index e04f14c..0000000
--- a/test/mjsunit/es7/regress/regress-443982.js
+++ /dev/null
@@ -1,24 +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.
-//
-// Flags: --harmony-object-observe
-
-var records;
-function observer(r) {
-  records = r;
-}
-
-Object.defineProperty(Array.prototype, '0', {
-  get: function() { return 0; },
-  set: function() { throw "boom!"; }
-});
-arr = [1, 2];
-Array.observe(arr, observer);
-arr.length = 0;
-assertEquals(0, arr.length);
-
-Object.deliverChangeRecords(observer);
-assertEquals(1, records.length);
-assertEquals('splice', records[0].type);
-assertArrayEquals([1, 2], records[0].removed);
diff --git a/test/mjsunit/es8/syntactic-tail-call-parsing-sloppy.js b/test/mjsunit/es8/syntactic-tail-call-parsing-sloppy.js
new file mode 100644
index 0000000..d026086
--- /dev/null
+++ b/test/mjsunit/es8/syntactic-tail-call-parsing-sloppy.js
@@ -0,0 +1,410 @@
+// 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: --allow-natives-syntax --harmony-explicit-tailcalls
+// Flags: --harmony-do-expressions
+
+var SyntaxErrorTests = [
+  { msg: "Unexpected expression inside tail call",
+    tests: [
+      { src: `()=>{ return continue  foo ; }`,
+        err: `                       ^^^`,
+      },
+      { src: `()=>{ return  continue 42 ; }`,
+        err: `                       ^^`,
+      },
+      { src: `()=>{ return  continue   new foo ()  ; }`,
+        err: `                         ^^^^^^^^^^`,
+      },
+      { src: `()=>{ loop: return  continue  loop ; }`,
+        err: `                              ^^^^`,
+      },
+      { src: `class A { foo() { return  continue   super.x ; } }`,
+        err: `                                     ^^^^^^^`,
+      },
+      { src: `()=>{ return  continue  this  ; }`,
+        err: `                        ^^^^`,
+      },
+      { src: `()=>{ return  continue class A {} ; }`,
+        err: `                       ^^^^^^^^^^`,
+      },
+      { src: `()=>{ return  continue class A extends B {} ; }`,
+        err: `                       ^^^^^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return  continue function A() { } ; }`,
+        err: `                       ^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return  continue { a: b, c: d} ; }`,
+        err: `                       ^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return  continue function* Gen() { yield 1; } ; }`,
+        err: `                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^`,
+      },
+      { src: `function A() { return  continue new.target ; }`,
+        err: `                                ^^^^^^^^^^`,
+      },
+      { src: `()=>{ return  continue () ; }`,
+        err: `                       ^^`,
+      },
+      { src: `()=>{ return  continue ( 42 ) ; }`,
+        err: `                       ^^^^^^`,
+      },
+      { src: "()=>{ return continue `123 ${foo} 34lk` ;  }",
+        err: `                      ^^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return continue do { x ? foo() : bar() ; } }`,
+        err: `                      ^^^^^^^^^^^^^^^^^^^^^^^^^^`,
+      },
+    ],
+  },
+  { msg: "Tail call expression is not allowed here",
+    tests: [
+      { src: `class A {}; class B extends A { constructor() { return continue foo () ; } }`,
+        err: `                                                       ^^^^^^^^^^^^^^^`,
+      },
+      { src: `class A extends continue f () {}; }`,
+        err: `                ^^^^^^^^^^^^^`,
+      },
+    ],
+  },
+  { msg: "Tail call expressions are not allowed in non-strict mode",
+    tests: [
+      { src: `()=>{ return  continue continue continue b()  ; }`,
+        err: `                                ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return  continue ( continue b() ) ; }`,
+        err: `                         ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return   continue  f()   - a ; }`,
+        err: `               ^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return b + continue   f()  ; }`,
+        err: `                 ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return 1, 2, 3,   continue  f() , 4  ; }`,
+        err: `                        ^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ var x =  continue  f ( ) ; }`,
+        err: `               ^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return   continue f () ? 1 : 2 ; }`,
+        err: `               ^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return (1, 2, 3, continue f()), 4; }`,
+        err: `                       ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return [1, 2, continue f() ] ;  }`,
+        err: `                    ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return [1, 2, ... continue f() ] ;  }`,
+        err: `                        ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return [1, 2, continue f(), 3 ] ;  }`,
+        err: `                    ^^^^^^^^^^^^`,
+      },
+      { src: "()=>{ return `123 ${a} ${ continue foo ( ) } 34lk` ;  }",
+        err: `                          ^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return g( 1, 2, continue f() ); }`,
+        err: `                      ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return continue f() || a; }`,
+        err: `             ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return a || b || c || continue f() || d; }`,
+        err: `                            ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return a && b && c && continue f() && d; }`,
+        err: `                            ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return a && b || c && continue f() ? d : e; }`,
+        err: `                            ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return a ? b : c && continue f() && d || e; }`,
+        err: `                          ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return continue foo() instanceof bar ; }`,
+        err: `             ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return bar instanceof continue foo() ; }`,
+        err: `                            ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return continue foo() in bar ; }`,
+        err: `             ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return bar in continue foo() ; }`,
+        err: `                    ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ function* G() { yield continue foo(); } }`,
+        err: `                            ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ (1, 2, 3, continue f() ) => {} }`,
+        err: `                ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ (... continue f()) => {}  }`,
+        err: `           ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ (a, b, c, ... continue f() ) => {}  }`,
+        err: `                    ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return a <= continue f(); }`,
+        err: `                  ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return b > continue f(); }`,
+        err: `                 ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return a << continue f(); }`,
+        err: `                  ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return b >> continue f(); }`,
+        err: `                  ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return c >>> continue f(); }`,
+        err: `                   ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return continue f() = a ; }`,
+        err: `             ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return a = continue f() ; }`,
+        err: `                 ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return a += continue f(); }`,
+        err: `                  ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return a ** continue f() ; }`,
+        err: `                  ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return delete continue foo() ; }`,
+        err: `                    ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ typeof continue foo()  ; }`,
+        err: `             ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return ~ continue foo() ; }`,
+        err: `               ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return void  continue foo() ; }`,
+        err: `                   ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return !continue foo() ; }`,
+        err: `              ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return -continue foo() ; }`,
+        err: `              ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return +continue foo() ; }`,
+        err: `              ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return ++ continue f( ) ; }`,
+        err: `                ^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return continue f()  ++; }`,
+        err: `             ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return continue f() --; }`,
+        err: `             ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return (continue foo()) () ;  }`,
+        err: `              ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ for (var i = continue foo(); i < 10; i++) bar(); }`,
+        err: `                   ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ for (var i = 0; i < continue foo(); i++) bar(); }`,
+        err: `                          ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ for (var i = 0; i < 10; continue foo()) bar(); }`,
+        err: `                              ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ if (continue foo()) bar(); }`,
+        err: `          ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ while (continue foo()) bar(); }`,
+        err: `             ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ do { smth; } while (continue foo()) ; }`,
+        err: `                          ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ throw continue foo() ; }`,
+        err: `            ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ switch (continue foo()) { case 1: break; } ; }`,
+        err: `              ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ with (continue foo()) { smth; } }`,
+        err: `            ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ let x = continue foo() }`,
+        err: `              ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ const c = continue  foo() }`,
+        err: `                ^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ try { return  continue   f ( ) ; } catch(e) {} }`,
+        err: `                    ^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ try { try { smth; } catch(e) { return  continue  f( ) ; } }`,
+        err: `                                             ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ try { try { smth; } catch(e) { return  continue  f( ) ; } } finally { bla; } }`,
+        err: `                                             ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ try { smth; } catch(e) { return  continue   f ( ) ; } finally { blah; } }`,
+        err: `                                       ^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ try { smth; } catch(e) { try { smth; } catch (e) { return  continue   f ( ) ; } } finally { blah; } }`,
+        err: `                                                                 ^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ for (var v in {a:0}) { return continue  foo () ; } }`,
+        err: `                                    ^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ for (var v of [1, 2, 3]) { return continue  foo () ; } }`,
+        err: `                                        ^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return continue  a.b.c.foo () ; }`,
+        err: `             ^^^^^^^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return continue  a().b.c().d.foo () ; }`,
+        err: `             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return continue  foo (1)(2)(3, 4) ; }`,
+        err: `             ^^^^^^^^^^^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return ( continue b() ) ; }`,
+        err: `               ^^^^^^^^^^^^`,
+      },
+      { src: "()=>{ return continue bar`ab cd ef` ; }",
+        err: `             ^^^^^^^^^^^^^^^^^^^^^^`,
+      },
+      { src: "()=>{ return continue bar`ab ${cd} ef` ; }",
+        err: `             ^^^^^^^^^^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return a || continue f() ; }`,
+        err: `                  ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return a && continue f() ; }`,
+        err: `                  ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return a , continue f() ; }`,
+        err: `                 ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ function* G() { return continue foo(); } }`,
+        err: `                             ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ function B() { return continue new.target() ; } }`,
+        err: `                            ^^^^^^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return continue do { x ? foo() : bar() ; }() }`,
+        err: `             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return continue (do { x ? foo() : bar() ; })() }`,
+        err: `             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return do { 1, continue foo() } }`,
+        err: `                     ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return do { x ? continue foo() : y } }`,
+        err: `                      ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return a || (b && continue c()); }`,
+        err: `                        ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return a && (b || continue c()); }`,
+        err: `                        ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return a || (b ? c : continue d()); }`,
+        err: `                           ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return 1, 2, 3, a || (b ? c : continue d()); }`,
+        err: `                                    ^^^^^^^^^^^^`,
+      },
+      { src: `()=> continue  (foo ()) ;`,
+        err: `     ^^^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=> a || continue  foo () ;`,
+        err: `          ^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=> a && continue  foo () ;`,
+        err: `          ^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=> a ? continue  foo () : b;`,
+        err: `         ^^^^^^^^^^^^^^^^`,
+      },
+    ],
+  },
+  { msg: "Undefined label 'foo'",
+    tests: [
+      { src: `()=>{ continue  foo () ; }`,
+        err: `                ^^^`,
+      },
+    ],
+  },
+];
+
+
+// Should parse successfully.
+var NoErrorTests = [
+  `()=>{ class A { foo() { return continue super.f() ; } } }`,
+  `()=>{ class A { foo() { return continue f() ; } } }`,
+  `()=>{ class A { foo() { return a || continue f() ; } } }`,
+  `()=>{ class A { foo() { return b && continue f() ; } } }`,
+];
+
+
+(function() {
+  for (var test_set of SyntaxErrorTests) {
+    var expected_message = "SyntaxError: " + test_set.msg;
+    for (var test of test_set.tests) {
+      var passed = true;
+      var e = null;
+      try {
+        Realm.eval(0, test.src);
+      } catch (ee) {
+        e = ee;
+      }
+      print("=======================================");
+      print("Expected | " + expected_message);
+      print("Source   | " + test.src);
+      print("         | " + test.err);
+
+      if (e === null) {
+        print("FAILED");
+        throw new Error("SyntaxError was not thrown");
+      }
+
+      var details = %GetExceptionDetails(e);
+      if (details.start_pos == undefined ||
+          details.end_pos == undefined) {
+        throw new Error("Bad message object returned");
+      }
+      var underline = " ".repeat(details.start_pos) +
+                      "^".repeat(details.end_pos - details.start_pos);
+      var passed = expected_message === e.toString() &&
+                   test.err === underline;
+
+      if (passed) {
+        print("PASSED");
+        print();
+      } else {
+        print("---------------------------------------");
+        print("Actual   | " + e);
+        print("Source   | " + test.src);
+        print("         | " + underline);
+        print("FAILED");
+        throw new Error("Test failed");
+      }
+    }
+  }
+})();
+
+
+(function() {
+  for (var src of NoErrorTests) {
+    print("=======================================");
+    print("Source   | " + src);
+    Realm.eval(0, src);
+    print("PASSED");
+    print();
+  }
+})();
diff --git a/test/mjsunit/es8/syntactic-tail-call-parsing.js b/test/mjsunit/es8/syntactic-tail-call-parsing.js
new file mode 100644
index 0000000..9ceff9c
--- /dev/null
+++ b/test/mjsunit/es8/syntactic-tail-call-parsing.js
@@ -0,0 +1,388 @@
+// 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: --allow-natives-syntax --harmony-explicit-tailcalls
+// Flags: --harmony-do-expressions
+"use strict";
+
+var SyntaxErrorTests = [
+  { msg: "Unexpected expression inside tail call",
+    tests: [
+      { src: `()=>{ return continue  foo ; }`,
+        err: `                       ^^^`,
+      },
+      { src: `()=>{ return  continue 42 ; }`,
+        err: `                       ^^`,
+      },
+      { src: `()=>{ return  continue   new foo ()  ; }`,
+        err: `                         ^^^^^^^^^^`,
+      },
+      { src: `()=>{ loop: return  continue  loop ; }`,
+        err: `                              ^^^^`,
+      },
+      { src: `class A { foo() { return  continue   super.x ; } }`,
+        err: `                                     ^^^^^^^`,
+      },
+      { src: `()=>{ return  continue  this  ; }`,
+        err: `                        ^^^^`,
+      },
+      { src: `()=>{ return  continue class A {} ; }`,
+        err: `                       ^^^^^^^^^^`,
+      },
+      { src: `()=>{ return  continue class A extends B {} ; }`,
+        err: `                       ^^^^^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return  continue function A() { } ; }`,
+        err: `                       ^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return  continue { a: b, c: d} ; }`,
+        err: `                       ^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return  continue function* Gen() { yield 1; } ; }`,
+        err: `                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^`,
+      },
+      { src: `function A() { return  continue new.target ; }`,
+        err: `                                ^^^^^^^^^^`,
+      },
+      { src: `()=>{ return  continue () ; }`,
+        err: `                       ^^`,
+      },
+      { src: `()=>{ return  continue ( 42 ) ; }`,
+        err: `                       ^^^^^^`,
+      },
+      { src: "()=>{ return continue `123 ${foo} 34lk` ;  }",
+        err: `                      ^^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return continue do { x ? foo() : bar() ; } }`,
+        err: `                      ^^^^^^^^^^^^^^^^^^^^^^^^^^`,
+      },
+    ],
+  },
+  { msg: "Tail call expression is not allowed here",
+    tests: [
+      { src: `()=>{ return  continue continue continue b()  ; }`,
+        err: `                                ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return  continue ( continue b() ) ; }`,
+        err: `                         ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return   continue  f()   - a ; }`,
+        err: `               ^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return b + continue   f()  ; }`,
+        err: `                 ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return 1, 2, 3,   continue  f() , 4  ; }`,
+        err: `                        ^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ var x =  continue  f ( ) ; }`,
+        err: `               ^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return   continue f () ? 1 : 2 ; }`,
+        err: `               ^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return (1, 2, 3, continue f()), 4; }`,
+        err: `                       ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return [1, 2, continue f() ] ;  }`,
+        err: `                    ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return [1, 2, ... continue f() ] ;  }`,
+        err: `                        ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return [1, 2, continue f(), 3 ] ;  }`,
+        err: `                    ^^^^^^^^^^^^`,
+      },
+      { src: "()=>{ return `123 ${a} ${ continue foo ( ) } 34lk` ;  }",
+        err: `                          ^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return g( 1, 2, continue f() ); }`,
+        err: `                      ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return continue f() || a; }`,
+        err: `             ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return a || b || c || continue f() || d; }`,
+        err: `                            ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return a && b && c && continue f() && d; }`,
+        err: `                            ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return a && b || c && continue f() ? d : e; }`,
+        err: `                            ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return a ? b : c && continue f() && d || e; }`,
+        err: `                          ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return continue foo() instanceof bar ; }`,
+        err: `             ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return bar instanceof continue foo() ; }`,
+        err: `                            ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return continue foo() in bar ; }`,
+        err: `             ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return bar in continue foo() ; }`,
+        err: `                    ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ function* G() { yield continue foo(); } }`,
+        err: `                            ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ (1, 2, 3, continue f() ) => {} }`,
+        err: `                ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ (... continue f()) => {}  }`,
+        err: `           ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ (a, b, c, ... continue f() ) => {}  }`,
+        err: `                    ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return a <= continue f(); }`,
+        err: `                  ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return b > continue f(); }`,
+        err: `                 ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return a << continue f(); }`,
+        err: `                  ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return b >> continue f(); }`,
+        err: `                  ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return c >>> continue f(); }`,
+        err: `                   ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return continue f() = a ; }`,
+        err: `             ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return a = continue f() ; }`,
+        err: `                 ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return a += continue f(); }`,
+        err: `                  ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return a ** continue f() ; }`,
+        err: `                  ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return delete continue foo() ; }`,
+        err: `                    ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ typeof continue foo()  ; }`,
+        err: `             ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return ~ continue foo() ; }`,
+        err: `               ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return void  continue foo() ; }`,
+        err: `                   ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return !continue foo() ; }`,
+        err: `              ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return -continue foo() ; }`,
+        err: `              ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return +continue foo() ; }`,
+        err: `              ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return ++ continue f( ) ; }`,
+        err: `                ^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return continue f()  ++; }`,
+        err: `             ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return continue f() --; }`,
+        err: `             ^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return (continue foo()) () ;  }`,
+        err: `              ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ for (var i = continue foo(); i < 10; i++) bar(); }`,
+        err: `                   ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ for (var i = 0; i < continue foo(); i++) bar(); }`,
+        err: `                          ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ for (var i = 0; i < 10; continue foo()) bar(); }`,
+        err: `                              ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ if (continue foo()) bar(); }`,
+        err: `          ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ while (continue foo()) bar(); }`,
+        err: `             ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ do { smth; } while (continue foo()) ; }`,
+        err: `                          ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ throw continue foo() ; }`,
+        err: `            ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ switch (continue foo()) { case 1: break; } ; }`,
+        err: `              ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ let x = continue foo() }`,
+        err: `              ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ const c = continue  foo() }`,
+        err: `                ^^^^^^^^^^^^^^^`,
+      },
+      { src: `class A {}; class B extends A { constructor() { return continue foo () ; } }`,
+        err: `                                                       ^^^^^^^^^^^^^^^`,
+      },
+      { src: `class A extends continue f () {}; }`,
+        err: `                ^^^^^^^^^^^^^`,
+      },
+    ],
+  },
+  { msg: "Tail call expression in try block",
+    tests: [
+      { src: `()=>{ try { return  continue   f ( ) ; } catch(e) {} }`,
+        err: `                    ^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ try { try { smth; } catch(e) { return  continue  f( ) ; } }`,
+        err: `                                             ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ try { try { smth; } catch(e) { return  continue  f( ) ; } } finally { bla; } }`,
+        err: `                                             ^^^^^^^^^^^^^^`,
+      },
+    ],
+  },
+  { msg: "Tail call expression in catch block when finally block is also present",
+    tests: [
+      { src: `()=>{ try { smth; } catch(e) { return  continue   f ( ) ; } finally { blah; } }`,
+        err: `                                       ^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ try { smth; } catch(e) { try { smth; } catch (e) { return  continue   f ( ) ; } } finally { blah; } }`,
+        err: `                                                                 ^^^^^^^^^^^^^^^^`,
+      },
+    ],
+  },
+  { msg: "Tail call expression in for-in/of body",
+    tests: [
+      { src: `()=>{ for (var v in {a:0}) { return continue  foo () ; } }`,
+        err: `                                    ^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ for (var v of [1, 2, 3]) { return continue  foo () ; } }`,
+        err: `                                        ^^^^^^^^^^^^^^^^`,
+      },
+    ],
+  },
+  { msg: "Tail call of a direct eval is not allowed",
+    tests: [
+      { src: `()=>{ return  continue  eval(" foo () " )  ; }`,
+        err: `                        ^^^^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return  a || continue  eval("", 1, 2)  ; }`,
+        err: `                             ^^^^^^^^^^^^^^`,
+      },
+      { src: `()=>{ return  a, continue  eval  ( )  ; }`,
+        err: `                           ^^^^^^^^^`,
+      },
+      { src: `()=> a, continue  eval  ( )  ; `,
+        err: `                  ^^^^^^^^^`,
+      },
+      { src: `()=> a || continue  eval  (' ' )  ; `,
+        err: `                    ^^^^^^^^^^^^`,
+      },
+    ],
+  },
+  { msg: "Undefined label 'foo'",
+    tests: [
+      { src: `()=>{ continue  foo () ; }`,
+        err: `                ^^^`,
+      },
+    ],
+  },
+];
+
+
+// Should parse successfully.
+var NoErrorTests = [
+  `()=>{ return continue  a.b.c.foo () ; }`,
+  `()=>{ return continue  a().b.c().d.foo () ; }`,
+  `()=>{ return continue  foo (1)(2)(3, 4) ; }`,
+  `()=>{ return continue (0, eval)(); }`,
+  `()=>{ return ( continue b() ) ; }`,
+  "()=>{ return continue bar`ab cd ef` ; }",
+  "()=>{ return continue bar`ab ${cd} ef` ; }",
+  `()=>{ return a || continue f() ; }`,
+  `()=>{ return a && continue f() ; }`,
+  `()=>{ return a , continue f() ; }`,
+  `()=>{ function* G() { return continue foo(); } }`,
+  `()=>{ class A { foo() { return continue super.f() ; } } }`,
+  `()=>{ function B() { return continue new.target() ; } }`,
+  `()=>{ return continue do { x ? foo() : bar() ; }() }`,
+  `()=>{ return continue (do { x ? foo() : bar() ; })() }`,
+  `()=>{ return do { 1, continue foo() } }`,
+  `()=>{ return do { x ? continue foo() : y } }`,
+  `()=>{ return a || (b && continue c()); }`,
+  `()=>{ return a && (b || continue c()); }`,
+  `()=>{ return a || (b ? c : continue d()); }`,
+  `()=>{ return 1, 2, 3, a || (b ? c : continue d()); }`,
+  `()=> continue  (foo ()) ;`,
+  `()=> a || continue  foo () ;`,
+  `()=> a && continue  foo () ;`,
+  `()=> a ? continue  foo () : b;`,
+];
+
+
+(function() {
+  for (var test_set of SyntaxErrorTests) {
+    var expected_message = "SyntaxError: " + test_set.msg;
+    for (var test of test_set.tests) {
+      var passed = true;
+      var e = null;
+      try {
+        eval(test.src);
+      } catch (ee) {
+        e = ee;
+      }
+      print("=======================================");
+      print("Expected | " + expected_message);
+      print("Source   | " + test.src);
+      print("         | " + test.err);
+
+      if (e === null) {
+        print("FAILED");
+        throw new Error("SyntaxError was not thrown");
+      }
+
+      var details = %GetExceptionDetails(e);
+      if (details.start_pos == undefined ||
+          details.end_pos == undefined) {
+        throw new Error("Bad message object returned");
+      }
+      var underline = " ".repeat(details.start_pos) +
+                      "^".repeat(details.end_pos - details.start_pos);
+      var passed = expected_message === e.toString() &&
+                   test.err === underline;
+
+      if (passed) {
+        print("PASSED");
+        print();
+      } else {
+        print("---------------------------------------");
+        print("Actual   | " + e);
+        print("Source   | " + test.src);
+        print("         | " + underline);
+        print("FAILED");
+        throw new Error("Test failed");
+      }
+    }
+  }
+})();
+
+
+(function() {
+  for (var src of NoErrorTests) {
+    print("=======================================");
+    print("Source   | " + src);
+    src = `"use strict"; ` + src;
+    Realm.eval(0, src);
+    print("PASSED");
+    print();
+  }
+})();
diff --git a/test/mjsunit/es8/syntactic-tail-call-simple.js b/test/mjsunit/es8/syntactic-tail-call-simple.js
new file mode 100644
index 0000000..ec7ade6
--- /dev/null
+++ b/test/mjsunit/es8/syntactic-tail-call-simple.js
@@ -0,0 +1,143 @@
+// 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: --allow-natives-syntax --harmony-explicit-tailcalls --stack-size=100
+
+//
+// Tail calls work only in strict mode.
+//
+(function() {
+  function f(n) {
+    if (n <= 0) {
+      return "foo";
+    }
+    return f(n - 1);
+  }
+  assertThrows(()=>{ f(1e5) });
+  %OptimizeFunctionOnNextCall(f);
+  assertThrows(()=>{ f(1e5) });
+})();
+
+
+//
+// Tail call normal functions.
+//
+(function() {
+  "use strict";
+  function f(n) {
+    if (n <= 0) {
+      return "foo";
+    }
+    return continue f(n - 1);
+  }
+  assertEquals("foo", f(1e5));
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals("foo", f(1e5));
+})();
+
+
+(function() {
+  "use strict";
+  function f(n) {
+    if (n <= 0) {
+      return  "foo";
+    }
+    return continue f(n - 1, 42);  // Call with arguments adaptor.
+  }
+  assertEquals("foo", f(1e5));
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals("foo", f(1e5));
+})();
+
+
+(function() {
+  "use strict";
+  function f(n){
+    if (n <= 0) {
+      return "foo";
+    }
+    return continue g(n - 1);
+  }
+  function g(n){
+    if (n <= 0) {
+      return "bar";
+    }
+    return continue f(n - 1);
+  }
+  assertEquals("foo", f(1e5));
+  assertEquals("bar", f(1e5 + 1));
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals("foo", f(1e5));
+  assertEquals("bar", f(1e5 + 1));
+})();
+
+
+(function() {
+  "use strict";
+  function f(n){
+    if (n <= 0) {
+      return "foo";
+    }
+    return continue g(n - 1, 42);  // Call with arguments adaptor.
+  }
+  function g(n){
+    if (n <= 0) {
+      return "bar";
+    }
+    return continue f(n - 1, 42);  // Call with arguments adaptor.
+  }
+  assertEquals("foo", f(1e5));
+  assertEquals("bar", f(1e5 + 1));
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals("foo", f(1e5));
+  assertEquals("bar", f(1e5 + 1));
+})();
+
+
+//
+// Tail call bound functions.
+//
+(function() {
+  "use strict";
+  function f0(n) {
+    if (n <= 0) {
+      return "foo";
+    }
+    return continue f_bound(n - 1);
+  }
+  var f_bound = f0.bind({});
+  function f(n) {
+    return continue f_bound(n);
+  }
+  assertEquals("foo", f(1e5));
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals("foo", f(1e5));
+})();
+
+
+(function() {
+  "use strict";
+  function f0(n){
+    if (n <= 0) {
+      return "foo";
+    }
+    return continue g_bound(n - 1);
+  }
+  function g0(n){
+    if (n <= 0) {
+      return "bar";
+    }
+    return continue f_bound(n - 1);
+  }
+  var f_bound = f0.bind({});
+  var g_bound = g0.bind({});
+  function f(n) {
+    return continue f_bound(n);
+  }
+  assertEquals("foo", f(1e5));
+  assertEquals("bar", f(1e5 + 1));
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals("foo", f(1e5));
+  assertEquals("bar", f(1e5 + 1));
+})();
diff --git a/test/mjsunit/es8/syntactic-tail-call.js b/test/mjsunit/es8/syntactic-tail-call.js
new file mode 100644
index 0000000..44936a4
--- /dev/null
+++ b/test/mjsunit/es8/syntactic-tail-call.js
@@ -0,0 +1,604 @@
+// 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: --allow-natives-syntax --harmony-explicit-tailcalls
+// Flags: --harmony-do-expressions
+
+"use strict";
+
+Error.prepareStackTrace = (error,stack) => {
+  error.strace = stack;
+  return error.message + "\n    at " + stack.join("\n    at ");
+}
+
+
+function CheckStackTrace(expected) {
+  var e = new Error();
+  e.stack;  // prepare stack trace
+  var stack = e.strace;
+  assertEquals("CheckStackTrace", stack[0].getFunctionName());
+  for (var i = 0; i < expected.length; i++) {
+    assertEquals(expected[i].name, stack[i + 1].getFunctionName());
+  }
+}
+%NeverOptimizeFunction(CheckStackTrace);
+
+
+function f(expected_call_stack, a, b) {
+  CheckStackTrace(expected_call_stack);
+  return a;
+}
+
+function f_153(expected_call_stack, a) {
+  CheckStackTrace(expected_call_stack);
+  return 153;
+}
+
+
+// Tail call when caller does not have an arguments adaptor frame.
+(function() {
+  // Caller and callee have same number of arguments.
+  function f1(a) {
+    CheckStackTrace([f1, test]);
+    return 10 + a;
+  }
+  function g1(a) { return continue f1(2); }
+
+  // Caller has more arguments than callee.
+  function f2(a) {
+    CheckStackTrace([f2, test]);
+    return 10 + a;
+  }
+  function g2(a, b, c) { return continue f2(2); }
+
+  // Caller has less arguments than callee.
+  function f3(a, b, c) {
+    CheckStackTrace([f3, test]);
+    return 10 + a + b + c;
+  }
+  function g3(a) { return continue f3(2, 3, 4); }
+
+  // Callee has arguments adaptor frame.
+  function f4(a, b, c) {
+    CheckStackTrace([f4, test]);
+    return 10 + a;
+  }
+  function g4(a) { return continue f4(2); }
+
+  function test() {
+    assertEquals(12, g1(1));
+    assertEquals(12, g2(1, 2, 3));
+    assertEquals(19, g3(1));
+    assertEquals(12, g4(1));
+  }
+  test();
+  test();
+  %OptimizeFunctionOnNextCall(test);
+  test();
+})();
+
+
+// Tail call when caller has an arguments adaptor frame.
+(function() {
+  // Caller and callee have same number of arguments.
+  function f1(a) {
+    CheckStackTrace([f1, test]);
+    return 10 + a;
+  }
+  function g1(a) { return continue f1(2); }
+
+  // Caller has more arguments than callee.
+  function f2(a) {
+    CheckStackTrace([f2, test]);
+    return 10 + a;
+  }
+  function g2(a, b, c) { return continue f2(2); }
+
+  // Caller has less arguments than callee.
+  function f3(a, b, c) {
+    CheckStackTrace([f3, test]);
+    return 10 + a + b + c;
+  }
+  function g3(a) { return continue f3(2, 3, 4); }
+
+  // Callee has arguments adaptor frame.
+  function f4(a, b, c) {
+    CheckStackTrace([f4, test]);
+    return 10 + a;
+  }
+  function g4(a) { return continue f4(2); }
+
+  function test() {
+    assertEquals(12, g1());
+    assertEquals(12, g2());
+    assertEquals(19, g3());
+    assertEquals(12, g4());
+  }
+  test();
+  test();
+  %OptimizeFunctionOnNextCall(test);
+  test();
+})();
+
+
+// Tail call bound function when caller does not have an arguments
+// adaptor frame.
+(function() {
+  // Caller and callee have same number of arguments.
+  function f1(a) {
+    assertEquals(153, this.a);
+    CheckStackTrace([f1, test]);
+    return 10 + a;
+  }
+  var b1 = f1.bind({a: 153});
+  function g1(a) { return continue b1(2); }
+
+  // Caller has more arguments than callee.
+  function f2(a) {
+    assertEquals(153, this.a);
+    CheckStackTrace([f2, test]);
+    return 10 + a;
+  }
+  var b2 = f2.bind({a: 153});
+  function g2(a, b, c) { return continue b2(2); }
+
+  // Caller has less arguments than callee.
+  function f3(a, b, c) {
+    assertEquals(153, this.a);
+    CheckStackTrace([f3, test]);
+    return 10 + a + b + c;
+  }
+  var b3 = f3.bind({a: 153});
+  function g3(a) { return continue b3(2, 3, 4); }
+
+  // Callee has arguments adaptor frame.
+  function f4(a, b, c) {
+    assertEquals(153, this.a);
+    CheckStackTrace([f4, test]);
+    return 10 + a;
+  }
+  var b4 = f4.bind({a: 153});
+  function g4(a) { return continue b4(2); }
+
+  function test() {
+    assertEquals(12, g1(1));
+    assertEquals(12, g2(1, 2, 3));
+    assertEquals(19, g3(1));
+    assertEquals(12, g4(1));
+  }
+  test();
+  test();
+  %OptimizeFunctionOnNextCall(test);
+  test();
+})();
+
+
+// Tail call bound function when caller has an arguments adaptor frame.
+(function() {
+  // Caller and callee have same number of arguments.
+  function f1(a) {
+    assertEquals(153, this.a);
+    CheckStackTrace([f1, test]);
+    return 10 + a;
+  }
+  var b1 = f1.bind({a: 153});
+  function g1(a) { return continue b1(2); }
+
+  // Caller has more arguments than callee.
+  function f2(a) {
+    assertEquals(153, this.a);
+    CheckStackTrace([f2, test]);
+    return 10 + a;
+  }
+  var b2 = f2.bind({a: 153});
+  function g2(a, b, c) { return continue b2(2); }
+
+  // Caller has less arguments than callee.
+  function f3(a, b, c) {
+    assertEquals(153, this.a);
+    CheckStackTrace([f3, test]);
+    return 10 + a + b + c;
+  }
+  var b3 = f3.bind({a: 153});
+  function g3(a) { return continue b3(2, 3, 4); }
+
+  // Callee has arguments adaptor frame.
+  function f4(a, b, c) {
+    assertEquals(153, this.a);
+    CheckStackTrace([f4, test]);
+    return 10 + a;
+  }
+  var b4 = f4.bind({a: 153});
+  function g4(a) { return continue b4(2); }
+
+  function test() {
+    assertEquals(12, g1());
+    assertEquals(12, g2());
+    assertEquals(19, g3());
+    assertEquals(12, g4());
+  }
+  test();
+  test();
+  %OptimizeFunctionOnNextCall(test);
+  test();
+})();
+
+
+// Tail calling from getter.
+(function() {
+  function g(v) {
+    CheckStackTrace([g, test]);
+    %DeoptimizeFunction(test);
+    return 153;
+  }
+  %NeverOptimizeFunction(g);
+
+  function f(v) {
+    return continue g();
+  }
+  %SetForceInlineFlag(f);
+
+  function test() {
+    var o = {};
+    o.__defineGetter__('p', f);
+    assertEquals(153, o.p);
+  }
+
+  test();
+  test();
+  %OptimizeFunctionOnNextCall(test);
+  test();
+})();
+
+
+// Tail calling from setter.
+(function() {
+  function g() {
+    CheckStackTrace([g, test]);
+    %DeoptimizeFunction(test);
+    return 153;
+  }
+  %NeverOptimizeFunction(g);
+
+  function f(v) {
+    return continue g();
+  }
+  %SetForceInlineFlag(f);
+
+  function test() {
+    var o = {};
+    o.__defineSetter__('q', f);
+    assertEquals(1, o.q = 1);
+  }
+
+  test();
+  test();
+  %OptimizeFunctionOnNextCall(test);
+  test();
+})();
+
+
+// Tail calling from constructor.
+(function() {
+  function g(context) {
+    CheckStackTrace([g, test]);
+    %DeoptimizeFunction(test);
+    return {x: 153};
+  }
+  %NeverOptimizeFunction(g);
+
+  function A() {
+    this.x = 42;
+    return continue g();
+  }
+
+  function test() {
+    var o = new A();
+    %DebugPrint(o);
+    assertEquals(153, o.x);
+  }
+
+  test();
+  test();
+  %OptimizeFunctionOnNextCall(test);
+  test();
+})();
+
+
+// Tail calling via various expressions.
+(function() {
+  function g1(a) {
+    return f([f, g1, test], false) || continue f([f, test], true);
+  }
+
+  function g2(a) {
+    return f([f, g2, test], true) && continue f([f, test], true);
+  }
+
+  function g3(a) {
+    return f([f, g3, test], 13), continue f([f, test], 153);
+  }
+
+  function g4(a) {
+    return f([f, g4, test], false) ||
+        (f([f, g4, test], true) && continue f([f, test], true));
+  }
+
+  function g5(a) {
+    return f([f, g5, test], true) &&
+        (f([f, g5, test], false) || continue f([f, test], true));
+  }
+
+  function g6(a) {
+    return f([f, g6, test], 13), f([f, g6, test], 42),
+        continue f([f, test], 153);
+  }
+
+  function g7(a) {
+    return f([f, g7, test], false) ||
+        (f([f, g7, test], false) ? continue f([f, test], true)
+             : continue f([f, test], true));
+  }
+
+  function g8(a) {
+    return f([f, g8, test], false) || f([f, g8, test], true) &&
+        continue f([f, test], true);
+  }
+
+  function g9(a) {
+    return f([f, g9, test], true) && f([f, g9, test], false) ||
+        continue f([f, test], true);
+  }
+
+  function g10(a) {
+    return f([f, g10, test], true) && f([f, g10, test], false) ||
+        f([f, g10, test], true) ?
+            f([f, g10, test], true) && f([f, g10, test], false) ||
+                continue f([f, test], true) :
+            f([f, g10, test], true) && f([f, g10, test], false) ||
+                continue f([f, test], true);
+  }
+
+  function test() {
+    assertEquals(true, g1());
+    assertEquals(true, g2());
+    assertEquals(153, g3());
+    assertEquals(true, g4());
+    assertEquals(true, g5());
+    assertEquals(153, g6());
+    assertEquals(true, g7());
+    assertEquals(true, g8());
+    assertEquals(true, g9());
+    assertEquals(true, g10());
+  }
+  test();
+  test();
+  %OptimizeFunctionOnNextCall(test);
+  test();
+})();
+
+
+// Tail calling from various statements.
+(function() {
+  function g3() {
+    for (var i = 0; i < 10; i++) {
+      return continue f_153([f_153, test]);
+    }
+  }
+
+  function g4() {
+    while (true) {
+      return continue f_153([f_153, test]);
+    }
+  }
+
+  function g5() {
+    do {
+      return continue f_153([f_153, test]);
+    } while (true);
+  }
+
+  function test() {
+    assertEquals(153, g3());
+    assertEquals(153, g4());
+    assertEquals(153, g5());
+  }
+  test();
+  test();
+  %OptimizeFunctionOnNextCall(test);
+  test();
+})();
+
+
+// Test tail calls from try-catch constructs.
+(function() {
+  function tc1(a) {
+    try {
+      f_153([f_153, tc1, test]);
+      return f_153([f_153, tc1, test]);
+    } catch(e) {
+      f_153([f_153, tc1, test]);
+    }
+  }
+
+  function tc2(a) {
+    try {
+      f_153([f_153, tc2, test]);
+      throw new Error("boom");
+    } catch(e) {
+      f_153([f_153, tc2, test]);
+      return continue f_153([f_153, test]);
+    }
+  }
+
+  function tc3(a) {
+    try {
+      f_153([f_153, tc3, test]);
+      throw new Error("boom");
+    } catch(e) {
+      f_153([f_153, tc3, test]);
+    }
+    f_153([f_153, tc3, test]);
+    return continue f_153([f_153, test]);
+  }
+
+  function test() {
+    assertEquals(153, tc1());
+    assertEquals(153, tc2());
+    assertEquals(153, tc3());
+  }
+  test();
+  test();
+  %OptimizeFunctionOnNextCall(test);
+  test();
+})();
+
+
+// Test tail calls from try-finally constructs.
+(function() {
+  function tf1(a) {
+    try {
+      f_153([f_153, tf1, test]);
+      return f_153([f_153, tf1, test]);
+    } finally {
+      f_153([f_153, tf1, test]);
+    }
+  }
+
+  function tf2(a) {
+    try {
+      f_153([f_153, tf2, test]);
+      throw new Error("boom");
+    } finally {
+      f_153([f_153, tf2, test]);
+      return continue f_153([f_153, test]);
+    }
+  }
+
+  function tf3(a) {
+    try {
+      f_153([f_153, tf3, test]);
+    } finally {
+      f_153([f_153, tf3, test]);
+    }
+    return continue f_153([f_153, test]);
+  }
+
+  function test() {
+    assertEquals(153, tf1());
+    assertEquals(153, tf2());
+    assertEquals(153, tf3());
+  }
+  test();
+  test();
+  %OptimizeFunctionOnNextCall(test);
+  test();
+})();
+
+
+// Test tail calls from try-catch-finally constructs.
+(function() {
+  function tcf1(a) {
+    try {
+      f_153([f_153, tcf1, test]);
+      return f_153([f_153, tcf1, test]);
+    } catch(e) {
+    } finally {
+      f_153([f_153, tcf1, test]);
+    }
+  }
+
+  function tcf2(a) {
+    try {
+      f_153([f_153, tcf2, test]);
+      throw new Error("boom");
+    } catch(e) {
+      f_153([f_153, tcf2, test]);
+      return f_153([f_153, tcf2, test]);
+    } finally {
+      f_153([f_153, tcf2, test]);
+    }
+  }
+
+  function tcf3(a) {
+    try {
+      f_153([f_153, tcf3, test]);
+      throw new Error("boom");
+    } catch(e) {
+      f_153([f_153, tcf3, test]);
+    } finally {
+      f_153([f_153, tcf3, test]);
+      return continue f_153([f_153, test]);
+    }
+  }
+
+  function tcf4(a) {
+    try {
+      f_153([f_153, tcf4, test]);
+      throw new Error("boom");
+    } catch(e) {
+      f_153([f_153, tcf4, test]);
+    } finally {
+      f_153([f_153, tcf4, test]);
+    }
+    return continue f_153([f_153, test]);
+  }
+
+  function test() {
+    assertEquals(153, tcf1());
+    assertEquals(153, tcf2());
+    assertEquals(153, tcf3());
+    assertEquals(153, tcf4());
+  }
+  test();
+  test();
+  %OptimizeFunctionOnNextCall(test);
+  test();
+})();
+
+
+// Test tail calls from arrow functions.
+(function () {
+  function g1(a) {
+    return continue (() => { return continue f_153([f_153, test]); })();
+  }
+
+  function g2(a) {
+    return continue (() => continue f_153([f_153, test]))();
+  }
+
+  function g3(a) {
+    var closure = () => f([f, closure, test], true)
+                              ? continue f_153([f_153, test])
+                              : continue f_153([f_153, test]);
+    return continue closure();
+  }
+
+  function test() {
+    assertEquals(153, g1());
+    assertEquals(153, g2());
+    assertEquals(153, g3());
+  }
+  test();
+  test();
+  %OptimizeFunctionOnNextCall(test);
+  test();
+})();
+
+
+// Test tail calls from do expressions.
+(function () {
+  function g1(a) {
+    var a = do { return continue f_153([f_153, test]); 42; };
+    return a;
+  }
+
+  function test() {
+    assertEquals(153, g1());
+  }
+  test();
+  test();
+  %OptimizeFunctionOnNextCall(test);
+  test();
+})();
diff --git a/test/mjsunit/eval-origin.js b/test/mjsunit/eval-origin.js
new file mode 100644
index 0000000..bb86ef3
--- /dev/null
+++ b/test/mjsunit/eval-origin.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: --nostress-opt
+
+Error.prepareStackTrace = function(exception, frames) {
+  return frames[0].getEvalOrigin();
+}
+
+var source = "new Error()";
+var eval_origin;
+var geval = eval;
+var log = [];
+
+(function() {
+  log.push([geval(source).stack, "17:13"]);
+  log.push([geval(source).stack, "18:13"]);
+  // log.push([geval(source).stack, "19:13"]);  TODO(4921).
+})();
+
+(function() {
+  log.push([eval(source).stack, "23:13"]);
+  log.push([eval(source).stack, "24:13"]);
+  // log.push([eval(source).stack, "25:13"]);  TODO(4921).
+})();
+
+log.push([eval(source).stack, "28:11"]);
+log.push([eval(source).stack, "29:11"]);
+// log.push([eval(source).stack, "30:11"]);  TODO(4921).
+
+Error.prepareStackTrace = undefined;
+
+for (var item of log) {
+  var stacktraceline = item[0];
+  var expectation = item[1];
+  var re = new RegExp(`:${expectation}\\)$`);
+  assertTrue(re.test(stacktraceline));
+}
diff --git a/test/mjsunit/for-in.js b/test/mjsunit/for-in.js
index bece37a..547c748 100644
--- a/test/mjsunit/for-in.js
+++ b/test/mjsunit/for-in.js
@@ -25,6 +25,8 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+// Flags: --noharmony-for-in
+
 function props(x) {
   var array = [];
   for (var p in x) array.push(p);
diff --git a/test/mjsunit/harmony/array-concat-array-proto-getter.js b/test/mjsunit/harmony/array-concat-array-proto-getter.js
new file mode 100644
index 0000000..9368e7f
--- /dev/null
+++ b/test/mjsunit/harmony/array-concat-array-proto-getter.js
@@ -0,0 +1,53 @@
+// 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.
+
+// Check that @@isConcatSpreadable is checked when set on Object.prototype
+
+"use strict"
+
+var array = [1, 2, 3];
+var object = {length: 1, '0': 'a'};
+
+function testConcatDefaults() {
+  assertEquals(array, [].concat(array));
+  assertEquals(array, array.concat([]));
+  assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
+  assertEquals([object], [].concat(object));
+  assertEquals([1, 2, 3, object], array.concat(object));
+  assertEquals([object], Array.prototype.concat.call(object,[]));
+  assertEquals([object, 1, 2, 3], Array.prototype.concat.call(object, array));
+  assertEquals([object, object], Array.prototype.concat.call(object, object));
+}
+
+testConcatDefaults();
+
+var concatSpreadable = false;
+Object.defineProperty(Array.prototype, Symbol.isConcatSpreadable, {
+    get() { return concatSpreadable },
+    configurable: true
+});
+
+assertEquals([[], array], [].concat(array));
+assertEquals([array, []], array.concat([]));
+assertEquals([array, array], array.concat(array));
+assertEquals([[], object], [].concat(object));
+assertEquals([array, object], array.concat(object));
+assertEquals([object, []], Array.prototype.concat.call(object,[]));
+assertEquals([object, array], Array.prototype.concat.call(object, array));
+assertEquals([object, object], Array.prototype.concat.call(object, object));
+
+concatSpreadable = true;
+
+assertEquals(array, [].concat(array));
+assertEquals(array, array.concat([]));
+assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
+assertEquals([object], [].concat(object));
+assertEquals([1, 2, 3, object], array.concat(object));
+assertEquals([object], Array.prototype.concat.call(object,[]));
+assertEquals([object, 1, 2, 3], Array.prototype.concat.call(object, array));
+assertEquals([object, object], Array.prototype.concat.call(object, object));
+
+
+delete Array.prototype[Symbol.isConcatSpreadable];
+testConcatDefaults();
diff --git a/test/mjsunit/harmony/array-concat-array-proto.js b/test/mjsunit/harmony/array-concat-array-proto.js
new file mode 100644
index 0000000..520178f
--- /dev/null
+++ b/test/mjsunit/harmony/array-concat-array-proto.js
@@ -0,0 +1,48 @@
+// 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.
+
+// Check that @@isConcatSpreadable is checked when set on Object.prototype
+
+"use strict"
+
+var array = [1, 2, 3];
+var object = {length: 1, '0': 'a'};
+
+function testConcatDefaults() {
+  assertEquals(array, [].concat(array));
+  assertEquals(array, array.concat([]));
+  assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
+  assertEquals([object], [].concat(object));
+  assertEquals([1, 2, 3, object], array.concat(object));
+  assertEquals([object], Array.prototype.concat.call(object,[]));
+  assertEquals([object, 1, 2, 3], Array.prototype.concat.call(object, array));
+  assertEquals([object, object], Array.prototype.concat.call(object, object));
+}
+
+testConcatDefaults();
+
+Array.prototype[Symbol.isConcatSpreadable] = false;
+
+assertEquals([[], array], [].concat(array));
+assertEquals([array, []], array.concat([]));
+assertEquals([array, array], array.concat(array));
+assertEquals([[], object], [].concat(object));
+assertEquals([array, object], array.concat(object));
+assertEquals([object, []], Array.prototype.concat.call(object,[]));
+assertEquals([object, array], Array.prototype.concat.call(object, array));
+assertEquals([object, object], Array.prototype.concat.call(object, object));
+
+Array.prototype[Symbol.isConcatSpreadable] = true;
+
+assertEquals(array, [].concat(array));
+assertEquals(array, array.concat([]));
+assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
+assertEquals([object], [].concat(object));
+assertEquals([1, 2, 3, object], array.concat(object));
+assertEquals([object], Array.prototype.concat.call(object,[]));
+assertEquals([object, 1, 2, 3], Array.prototype.concat.call(object, array));
+assertEquals([object, object], Array.prototype.concat.call(object, object));
+
+delete Array.prototype[Symbol.isConcatSpreadable];
+testConcatDefaults();
diff --git a/test/mjsunit/harmony/array-concat-object-proto-dict-getter.js b/test/mjsunit/harmony/array-concat-object-proto-dict-getter.js
new file mode 100644
index 0000000..6e61588
--- /dev/null
+++ b/test/mjsunit/harmony/array-concat-object-proto-dict-getter.js
@@ -0,0 +1,57 @@
+// 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.
+
+// Check that @@isConcatSpreadable is checked when set on Object.prototype
+// with a dictionary backing store.
+
+// Force Object.prototype into dictionary backing store by adding many
+// properties.
+for (var i = 0; i < 10*1000; i++) {
+  Object.prototype['generatedProperty'+i] = true;
+}
+
+var array = [1, 2, 3];
+var object = {length: 1, '0': 'a'};
+
+function testConcatDefaults() {
+  assertEquals(array, [].concat(array));
+  assertEquals(array, array.concat([]));
+  assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
+  assertEquals([object], [].concat(object));
+  assertEquals([1, 2, 3, object], array.concat(object));
+  assertEquals([object], Array.prototype.concat.call(object,[]));
+  assertEquals([object, 1, 2, 3], Array.prototype.concat.call(object, array));
+  assertEquals([object, object], Array.prototype.concat.call(object, object));
+}
+
+testConcatDefaults();
+
+var concatSpreadable = false;
+Object.defineProperty(Object.prototype, Symbol.isConcatSpreadable, {
+  get() { return concatSpreadable },
+  configurable: true
+});
+
+assertEquals([[], array], [].concat(array));
+assertEquals([array, []], array.concat([]));
+assertEquals([array, array], array.concat(array));
+assertEquals([[], object], [].concat(object));
+assertEquals([array, object], array.concat(object));
+assertEquals([object, []], Array.prototype.concat.call(object,[]));
+assertEquals([object, array], Array.prototype.concat.call(object, array));
+assertEquals([object, object], Array.prototype.concat.call(object, object));
+
+concatSpreadable = true;
+
+assertEquals(array, [].concat(array));
+assertEquals(array, array.concat([]));
+assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
+assertEquals(['a'], [].concat(object));
+assertEquals([1, 2, 3, 'a'], array.concat(object));
+assertEquals(['a'], Array.prototype.concat.call(object,[]));
+assertEquals(['a', 1, 2, 3], Array.prototype.concat.call(object, array));
+assertEquals(['a', 'a'], Array.prototype.concat.call(object, object));
+
+delete Object.prototype[Symbol.isConcatSpreadable];
+testConcatDefaults();
diff --git a/test/mjsunit/harmony/array-concat-object-proto-dict.js b/test/mjsunit/harmony/array-concat-object-proto-dict.js
new file mode 100644
index 0000000..c817006
--- /dev/null
+++ b/test/mjsunit/harmony/array-concat-object-proto-dict.js
@@ -0,0 +1,53 @@
+// 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.
+
+// Check that @@isConcatSpreadable is checked when set on Object.prototype
+// with a dictionary backing store.
+
+// Force Object.prototype into dictionary backing store by adding many
+// properties.
+for (var i = 0; i < 10*1000; i++) {
+  Object.prototype['generatedProperty'+i] = true;
+}
+
+var array = [1, 2, 3];
+var object = {length: 1, '0': 'a'};
+
+function testConcatDefaults() {
+  assertEquals(array, [].concat(array));
+  assertEquals(array, array.concat([]));
+  assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
+  assertEquals([object], [].concat(object));
+  assertEquals([1, 2, 3, object], array.concat(object));
+  assertEquals([object], Array.prototype.concat.call(object,[]));
+  assertEquals([object, 1, 2, 3], Array.prototype.concat.call(object, array));
+  assertEquals([object, object], Array.prototype.concat.call(object, object));
+}
+
+testConcatDefaults();
+
+Object.prototype[Symbol.isConcatSpreadable] = false;
+
+assertEquals([[], array], [].concat(array));
+assertEquals([array, []], array.concat([]));
+assertEquals([array, array], array.concat(array));
+assertEquals([[], object], [].concat(object));
+assertEquals([array, object], array.concat(object));
+assertEquals([object, []], Array.prototype.concat.call(object,[]));
+assertEquals([object, array], Array.prototype.concat.call(object, array));
+assertEquals([object, object], Array.prototype.concat.call(object, object));
+
+Object.prototype[Symbol.isConcatSpreadable] = true;
+
+assertEquals(array, [].concat(array));
+assertEquals(array, array.concat([]));
+assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
+assertEquals(['a'], [].concat(object));
+assertEquals([1, 2, 3, 'a'], array.concat(object));
+assertEquals(['a'], Array.prototype.concat.call(object,[]));
+assertEquals(['a', 1, 2, 3], Array.prototype.concat.call(object, array));
+assertEquals(['a', 'a'], Array.prototype.concat.call(object, object));
+
+delete Object.prototype[Symbol.isConcatSpreadable];
+testConcatDefaults();
diff --git a/test/mjsunit/harmony/array-concat-object-proto-generic-dict.js b/test/mjsunit/harmony/array-concat-object-proto-generic-dict.js
new file mode 100644
index 0000000..7b61422
--- /dev/null
+++ b/test/mjsunit/harmony/array-concat-object-proto-generic-dict.js
@@ -0,0 +1,65 @@
+// 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.
+
+// Check that @@isConcatSpreadable is checked when set on Object.prototype
+// with a dictionary backing store.
+
+// Force Object.prototype into dictionary backing store by adding many
+// properties.
+for (var i = 0; i < 10*1000; i++) {
+  Object.prototype['generatedProperty'+i] = true;
+}
+
+var array = [1, 2, 3];
+var object = {length: 1, '0': 'a'};
+
+function SetProperty(receiver, key, value) {
+  receiver[key] = value;
+}
+
+// Force the Keyed Store IC in SetProperty to be generic.
+var receiver = {};
+for (var i = 0; i < 100; i++) {
+  SetProperty(receiver, 'prop'+i, 'value');
+}
+
+function testConcatDefaults() {
+  assertEquals(array, [].concat(array));
+  assertEquals(array, array.concat([]));
+  assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
+  assertEquals([object], [].concat(object));
+  assertEquals([1, 2, 3, object], array.concat(object));
+  assertEquals([object], Array.prototype.concat.call(object,[]));
+  assertEquals([object, 1, 2, 3], Array.prototype.concat.call(object, array));
+  assertEquals([object, object], Array.prototype.concat.call(object, object));
+}
+
+testConcatDefaults();
+
+// Use a generic IC to set @@isConcatSpreadable
+SetProperty(Object.prototype, Symbol.isConcatSpreadable, false);
+
+assertEquals([[], array], [].concat(array));
+assertEquals([array, []], array.concat([]));
+assertEquals([array, array], array.concat(array));
+assertEquals([[], object], [].concat(object));
+assertEquals([array, object], array.concat(object));
+assertEquals([object, []], Array.prototype.concat.call(object,[]));
+assertEquals([object, array], Array.prototype.concat.call(object, array));
+assertEquals([object, object], Array.prototype.concat.call(object, object));
+
+// Use a generic IC to set @@isConcatSpreadable
+SetProperty(Object.prototype, Symbol.isConcatSpreadable, true);
+
+assertEquals(array, [].concat(array));
+assertEquals(array, array.concat([]));
+assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
+assertEquals(['a'], [].concat(object));
+assertEquals([1, 2, 3, 'a'], array.concat(object));
+assertEquals(['a'], Array.prototype.concat.call(object,[]));
+assertEquals(['a', 1, 2, 3], Array.prototype.concat.call(object, array));
+assertEquals(['a', 'a'], Array.prototype.concat.call(object, object));
+
+delete Object.prototype[Symbol.isConcatSpreadable];
+testConcatDefaults();
diff --git a/test/mjsunit/harmony/array-concat-object-proto.js b/test/mjsunit/harmony/array-concat-object-proto.js
new file mode 100644
index 0000000..307326c
--- /dev/null
+++ b/test/mjsunit/harmony/array-concat-object-proto.js
@@ -0,0 +1,48 @@
+// 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.
+
+// Check that @@isConcatSpreadable is checked when set on Object.prototype
+
+"use strict"
+
+var array = [1, 2, 3];
+var object = {length: 1, '0': 'a'};
+
+function testConcatDefaults() {
+  assertEquals(array, [].concat(array));
+  assertEquals(array, array.concat([]));
+  assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
+  assertEquals([object], [].concat(object));
+  assertEquals([1, 2, 3, object], array.concat(object));
+  assertEquals([object], Array.prototype.concat.call(object,[]));
+  assertEquals([object, 1, 2, 3], Array.prototype.concat.call(object, array));
+  assertEquals([object, object], Array.prototype.concat.call(object, object));
+}
+
+testConcatDefaults();
+
+Object.prototype[Symbol.isConcatSpreadable] = false;
+
+assertEquals([[], array], [].concat(array));
+assertEquals([array, []], array.concat([]));
+assertEquals([array, array], array.concat(array));
+assertEquals([[], object], [].concat(object));
+assertEquals([array, object], array.concat(object));
+assertEquals([object, []], Array.prototype.concat.call(object,[]));
+assertEquals([object, array], Array.prototype.concat.call(object, array));
+assertEquals([object, object], Array.prototype.concat.call(object, object));
+
+Object.prototype[Symbol.isConcatSpreadable] = true;
+
+assertEquals(array, [].concat(array));
+assertEquals(array, array.concat([]));
+assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
+assertEquals(['a'], [].concat(object));
+assertEquals([1, 2, 3, 'a'], array.concat(object));
+assertEquals(['a'], Array.prototype.concat.call(object,[]));
+assertEquals(['a', 1, 2, 3], Array.prototype.concat.call(object, array));
+assertEquals(['a', 'a'], Array.prototype.concat.call(object, object));
+
+delete Object.prototype[Symbol.isConcatSpreadable];
+testConcatDefaults();
diff --git a/test/mjsunit/harmony/async-arrow-lexical-arguments.js b/test/mjsunit/harmony/async-arrow-lexical-arguments.js
new file mode 100644
index 0000000..44d38a4
--- /dev/null
+++ b/test/mjsunit/harmony/async-arrow-lexical-arguments.js
@@ -0,0 +1,42 @@
+// 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
+
+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 " + PrettyPrint(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);
+};
+
+assertEqualsAsync("[1,2,3]", () => (function() {
+  return (async () => JSON.stringify([...arguments]))();
+})(1, 2, 3));
+
+assertEqualsAsync("[4,5,6]",
+    () => (function() {
+      return (async () => {
+        return JSON.stringify([...await arguments]) })();
+      })(4, 5, 6));
diff --git a/test/mjsunit/harmony/async-arrow-lexical-new.target.js b/test/mjsunit/harmony/async-arrow-lexical-new.target.js
new file mode 100644
index 0000000..72b29e6
--- /dev/null
+++ b/test/mjsunit/harmony/async-arrow-lexical-new.target.js
@@ -0,0 +1,43 @@
+// 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
+
+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 " + PrettyPrint(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);
+};
+
+class BaseClass {
+  constructor() {
+    return async () => new.target;
+  }
+}
+
+class ChildClass extends BaseClass {}
+
+assertEqualsAsync(BaseClass, () => new BaseClass()());
+assertEqualsAsync(ChildClass, () => new ChildClass()());
diff --git a/test/mjsunit/harmony/async-arrow-lexical-super.js b/test/mjsunit/harmony/async-arrow-lexical-super.js
new file mode 100644
index 0000000..78f5d55
--- /dev/null
+++ b/test/mjsunit/harmony/async-arrow-lexical-super.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: --harmony-async-await --allow-natives-syntax
+
+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 " + PrettyPrint(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);
+};
+
+class BaseClass {
+  constructor(x) {
+    this.name_ = x;
+  }
+  get name() { return this.name_; }
+};
+
+class DeferredSuperCall extends BaseClass {
+  constructor(x) {
+    return async() => super(x);
+  }
+};
+
+assertEqualsAsync(
+  "LexicalSuperCall",
+  () => new DeferredSuperCall("LexicalSuperCall")().then(x => x.name));
+
+
+class DeferredSuperProperty extends BaseClass {
+  deferredName() { return async() => super.name; }
+};
+
+assertEqualsAsync(
+  "LexicalSuperProperty",
+  () => new DeferredSuperProperty("LexicalSuperProperty").deferredName()());
diff --git a/test/mjsunit/harmony/async-arrow-lexical-this.js b/test/mjsunit/harmony/async-arrow-lexical-this.js
new file mode 100644
index 0000000..182db47
--- /dev/null
+++ b/test/mjsunit/harmony/async-arrow-lexical-this.js
@@ -0,0 +1,48 @@
+// 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
+
+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 " + PrettyPrint(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 O = {
+  [Symbol.toStringTag]: "LexicalThis",
+  run(n) {
+    return async passFail => `${n}. ${passFail}: ${this}`;
+  },
+};
+
+assertEqualsAsync("1. PASS: [object LexicalThis]", () => O.run(1)("PASS"));
+
+var O2 = {
+  [Symbol.toStringTag]: "LexicalThis",
+  run: O.run(2)
+};
+
+assertEqualsAsync("2. PASS: [object LexicalThis]", () => O2.run("PASS"));
diff --git a/test/mjsunit/harmony/async-await-basic.js b/test/mjsunit/harmony/async-await-basic.js
new file mode 100644
index 0000000..d0888ea
--- /dev/null
+++ b/test/mjsunit/harmony/async-await-basic.js
@@ -0,0 +1,347 @@
+// 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
+
+// Do not install `AsyncFunction` constructor on global object
+
+function assertThrowsAsync(run, errorType, message) {
+  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 " + PrettyPrint(promise));
+  }
+
+  promise.then(function(value) { hadValue = true; actual = value; },
+               function(error) { hadError = true; actual = error; });
+
+  assertFalse(hadValue || hadError);
+
+  %RunMicrotasks();
+
+  if (!hadError) {
+    throw new MjsUnitAssertionError(
+        "Expected " + run + "() to throw " + errorType.name +
+        ", but did not throw.");
+  }
+  if (!(actual instanceof errorType))
+    throw new MjsUnitAssertionError(
+        "Expected " + run + "() to throw " + errorType.name +
+        ", but threw '" + actual + "'");
+  if (message !== void 0 && actual.message !== message)
+    throw new MjsUnitAssertionError(
+        "Expected " + run + "() to throw '" + message + "', but threw '" +
+        actual.message + "'");
+};
+
+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 " + PrettyPrint(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);
+};
+
+assertEquals(undefined, this.AsyncFunction);
+let AsyncFunction = (async function() {}).constructor;
+
+// Let functionPrototype be the intrinsic object %AsyncFunctionPrototype%.
+async function asyncFunctionForProto() {}
+assertEquals(AsyncFunction.prototype,
+             Object.getPrototypeOf(asyncFunctionForProto));
+assertEquals(AsyncFunction.prototype,
+             Object.getPrototypeOf(async function() {}));
+assertEquals(AsyncFunction.prototype, Object.getPrototypeOf(async () => {}));
+assertEquals(AsyncFunction.prototype,
+             Object.getPrototypeOf({ async method() {} }.method));
+assertEquals(AsyncFunction.prototype, Object.getPrototypeOf(AsyncFunction()));
+assertEquals(AsyncFunction.prototype,
+             Object.getPrototypeOf(new AsyncFunction()));
+
+// AsyncFunctionCreate does not produce an object with a Prototype
+assertEquals(undefined, asyncFunctionForProto.prototype);
+assertEquals(false, asyncFunctionForProto.hasOwnProperty("prototype"));
+assertEquals(undefined, (async function() {}).prototype);
+assertEquals(false, (async function() {}).hasOwnProperty("prototype"));
+assertEquals(undefined, (async() => {}).prototype);
+assertEquals(false, (async() => {}).hasOwnProperty("prototype"));
+assertEquals(undefined, ({ async method() {} }).method.prototype);
+assertEquals(false, ({ async method() {} }).method.hasOwnProperty("prototype"));
+assertEquals(undefined, AsyncFunction().prototype);
+assertEquals(false, AsyncFunction().hasOwnProperty("prototype"));
+assertEquals(undefined, (new AsyncFunction()).prototype);
+assertEquals(false, (new AsyncFunction()).hasOwnProperty("prototype"));
+
+assertEquals(1, async function(a) { await 1; }.length);
+assertEquals(2, async function(a, b) { await 1; }.length);
+assertEquals(1, async function(a, b = 2) { await 1; }.length);
+assertEquals(2, async function(a, b, ...c) { await 1; }.length);
+
+assertEquals(1, (async(a) => await 1).length);
+assertEquals(2, (async(a, b) => await 1).length);
+assertEquals(1, (async(a, b = 2) => await 1).length);
+assertEquals(2, (async(a, b, ...c) => await 1).length);
+
+assertEquals(1, ({ async f(a) { await 1; } }).f.length);
+assertEquals(2, ({ async f(a, b) { await 1; } }).f.length);
+assertEquals(1, ({ async f(a, b = 2) { await 1; } }).f.length);
+assertEquals(2, ({ async f(a, b, ...c) { await 1; } }).f.length);
+
+assertEquals(1, AsyncFunction("a", "await 1").length);
+assertEquals(2, AsyncFunction("a", "b", "await 1").length);
+assertEquals(1, AsyncFunction("a", "b = 2", "await 1").length);
+assertEquals(2, AsyncFunction("a", "b", "...c", "await 1").length);
+
+assertEquals(1, (new AsyncFunction("a", "await 1")).length);
+assertEquals(2, (new AsyncFunction("a", "b", "await 1")).length);
+assertEquals(1, (new AsyncFunction("a", "b = 2", "await 1")).length);
+assertEquals(2, (new AsyncFunction("a", "b", "...c", "await 1")).length);
+
+// AsyncFunction.prototype[ @@toStringTag ]
+var descriptor =
+    Object.getOwnPropertyDescriptor(AsyncFunction.prototype,
+                                    Symbol.toStringTag);
+assertEquals("AsyncFunction", descriptor.value);
+assertEquals(false, descriptor.enumerable);
+assertEquals(false, descriptor.writable);
+assertEquals(true, descriptor.configurable);
+
+assertEquals(1, AsyncFunction.length);
+
+// Let F be ! FunctionAllocate(functionPrototype, Strict, "non-constructor")
+async function asyncNonConstructorDecl() {}
+assertThrows(
+    () => new asyncNonConstructorDecl(), TypeError);
+assertThrows(
+    () => new (async function() {}), TypeError);
+assertThrows(
+    () => new ({ async nonConstructor() {} }).nonConstructor(), TypeError);
+assertThrows(
+    () => new (() => "not a constructor!"), TypeError);
+assertThrows(
+    () => new (AsyncFunction()), TypeError);
+assertThrows(
+    () => new (new AsyncFunction()), TypeError);
+
+// Normal completion
+async function asyncDecl() { return "test"; }
+assertEqualsAsync("test", asyncDecl);
+assertEqualsAsync("test2", async function() { return "test2"; });
+assertEqualsAsync("test3", async () => "test3");
+assertEqualsAsync("test4", () => ({ async f() { return "test4"; } }).f());
+assertEqualsAsync("test5", () => AsyncFunction("no", "return 'test' + no;")(5));
+assertEqualsAsync("test6",
+                  () => (new AsyncFunction("no", "return 'test' + no;"))(6));
+
+class MyError extends Error {};
+
+// Throw completion
+async function asyncDeclThrower(e) { throw new MyError(e); }
+assertThrowsAsync(() => asyncDeclThrower("boom!"), MyError, "boom!");
+assertThrowsAsync(
+  () => (async function(e) { throw new MyError(e); })("boom!!!"),
+  MyError, "boom!!!");
+assertThrowsAsync(
+  () => (async e => { throw new MyError(e) })("boom!!"), MyError, "boom!!");
+assertThrowsAsync(
+  () => ({ async thrower(e) { throw new MyError(e); } }).thrower("boom!1!"),
+  MyError, "boom!1!");
+assertThrowsAsync(
+  () => AsyncFunction("msg", "throw new MyError(msg)")("boom!2!!"),
+  MyError, "boom!2!!");
+assertThrowsAsync(
+  () => (new AsyncFunction("msg", "throw new MyError(msg)"))("boom!2!!!"),
+  MyError, "boom!2!!!");
+
+function resolveLater(value) { return Promise.resolve(value); }
+function rejectLater(error) { return Promise.reject(error); }
+
+// Resume after Normal completion
+var log = [];
+async function resumeAfterNormal(value) {
+  log.push("start:" + value);
+  value = await resolveLater(value + 1);
+  log.push("resume:" + value);
+  value = await resolveLater(value + 1);
+  log.push("resume:" + value);
+  return value + 1;
+}
+
+assertEqualsAsync(4, () => resumeAfterNormal(1));
+assertEquals("start:1 resume:2 resume:3", log.join(" "));
+
+var O = {
+  async resumeAfterNormal(value) {
+    log.push("start:" + value);
+    value = await resolveLater(value + 1);
+    log.push("resume:" + value);
+    value = await resolveLater(value + 1);
+    log.push("resume:" + value);
+    return value + 1;
+  }
+};
+log = [];
+assertEqualsAsync(5, () => O.resumeAfterNormal(2));
+assertEquals("start:2 resume:3 resume:4", log.join(" "));
+
+var resumeAfterNormalArrow = async (value) => {
+  log.push("start:" + value);
+  value = await resolveLater(value + 1);
+  log.push("resume:" + value);
+  value = await resolveLater(value + 1);
+  log.push("resume:" + value);
+  return value + 1;
+};
+log = [];
+assertEqualsAsync(6, () => resumeAfterNormalArrow(3));
+assertEquals("start:3 resume:4 resume:5", log.join(" "));
+
+var resumeAfterNormalEval = AsyncFunction("value", `
+    log.push("start:" + value);
+    value = await resolveLater(value + 1);
+    log.push("resume:" + value);
+    value = await resolveLater(value + 1);
+    log.push("resume:" + value);
+    return value + 1;`);
+log = [];
+assertEqualsAsync(7, () => resumeAfterNormalEval(4));
+assertEquals("start:4 resume:5 resume:6", log.join(" "));
+
+var resumeAfterNormalNewEval = new AsyncFunction("value", `
+    log.push("start:" + value);
+    value = await resolveLater(value + 1);
+    log.push("resume:" + value);
+    value = await resolveLater(value + 1);
+    log.push("resume:" + value);
+    return value + 1;`);
+log = [];
+assertEqualsAsync(8, () => resumeAfterNormalNewEval(5));
+assertEquals("start:5 resume:6 resume:7", log.join(" "));
+
+// Resume after Throw completion
+async function resumeAfterThrow(value) {
+  log.push("start:" + value);
+  try {
+    value = await rejectLater("throw1");
+  } catch (e) {
+    log.push("resume:" + e);
+  }
+  try {
+    value = await rejectLater("throw2");
+  } catch (e) {
+    log.push("resume:" + e);
+  }
+  return value + 1;
+}
+
+log = [];
+assertEqualsAsync(2, () => resumeAfterThrow(1));
+assertEquals("start:1 resume:throw1 resume:throw2", log.join(" "));
+
+var O = {
+  async resumeAfterThrow(value) {
+    log.push("start:" + value);
+    try {
+      value = await rejectLater("throw1");
+    } catch (e) {
+      log.push("resume:" + e);
+    }
+    try {
+      value = await rejectLater("throw2");
+    } catch (e) {
+      log.push("resume:" + e);
+    }
+    return value + 1;
+  }
+}
+log = [];
+assertEqualsAsync(3, () => O.resumeAfterThrow(2));
+assertEquals("start:2 resume:throw1 resume:throw2", log.join(" "));
+
+var resumeAfterThrowArrow = async (value) => {
+  log.push("start:" + value);
+  try {
+    value = await rejectLater("throw1");
+  } catch (e) {
+    log.push("resume:" + e);
+  }
+  try {
+    value = await rejectLater("throw2");
+  } catch (e) {
+    log.push("resume:" + e);
+  }
+ return value + 1;
+};
+
+log = [];
+
+assertEqualsAsync(4, () => resumeAfterThrowArrow(3));
+assertEquals("start:3 resume:throw1 resume:throw2", log.join(" "));
+
+var resumeAfterThrowEval = AsyncFunction("value", `
+    log.push("start:" + value);
+    try {
+      value = await rejectLater("throw1");
+    } catch (e) {
+      log.push("resume:" + e);
+    }
+    try {
+      value = await rejectLater("throw2");
+    } catch (e) {
+      log.push("resume:" + e);
+    }
+    return value + 1;`);
+log = [];
+assertEqualsAsync(5, () => resumeAfterThrowEval(4));
+assertEquals("start:4 resume:throw1 resume:throw2", log.join(" "));
+
+var resumeAfterThrowNewEval = new AsyncFunction("value", `
+    log.push("start:" + value);
+    try {
+      value = await rejectLater("throw1");
+    } catch (e) {
+      log.push("resume:" + e);
+    }
+    try {
+      value = await rejectLater("throw2");
+    } catch (e) {
+      log.push("resume:" + e);
+    }
+    return value + 1;`);
+log = [];
+assertEqualsAsync(6, () => resumeAfterThrowNewEval(5));
+assertEquals("start:5 resume:throw1 resume:throw2", log.join(" "));
+
+async function foo() {}
+assertEquals("async function foo() {}", foo.toString());
+assertEquals("async function () {}", async function() {}.toString());
+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));
diff --git a/test/mjsunit/harmony/atomics.js b/test/mjsunit/harmony/atomics.js
index bf27eb4..e608df3 100644
--- a/test/mjsunit/harmony/atomics.js
+++ b/test/mjsunit/harmony/atomics.js
@@ -16,26 +16,19 @@
   return value;
 }
 
-function toRangeClamped(value) {
-  if (value < this.min) return this.min;
-  if (value > this.max) return this.max;
-  return value;
-}
-
 function makeConstructorObject(constr, min, max, toRange) {
   var o = {constr: constr, min: min, max: max};
-  o.toRange = toRange.bind(o);
+  o.toRange = toRangeWrapped.bind(o);
   return o;
 }
 
 var IntegerTypedArrayConstructors = [
-  makeConstructorObject(Int8Array, -128, 127, toRangeWrapped),
-  makeConstructorObject(Int16Array, -32768, 32767, toRangeWrapped),
-  makeConstructorObject(Int32Array, -0x80000000, 0x7fffffff, toRangeWrapped),
-  makeConstructorObject(Uint8Array, 0, 255, toRangeWrapped),
-  makeConstructorObject(Uint8ClampedArray, 0, 255, toRangeClamped),
-  makeConstructorObject(Uint16Array, 0, 65535, toRangeWrapped),
-  makeConstructorObject(Uint32Array, 0, 0xffffffff, toRangeWrapped),
+  makeConstructorObject(Int8Array, -128, 127),
+  makeConstructorObject(Int16Array, -32768, 32767),
+  makeConstructorObject(Int32Array, -0x80000000, 0x7fffffff),
+  makeConstructorObject(Uint8Array, 0, 255),
+  makeConstructorObject(Uint16Array, 0, 65535),
+  makeConstructorObject(Uint32Array, 0, 0xffffffff),
 ];
 
 (function TestBadArray() {
@@ -44,9 +37,13 @@
   var sab = new SharedArrayBuffer(128);
   var sf32a = new Float32Array(sab);
   var sf64a = new Float64Array(sab);
+  var u8ca = new Uint8ClampedArray(sab);
 
   // Atomic ops required integer shared typed arrays
-  [undefined, 1, 'hi', 3.4, ab, u32a, sab, sf32a, sf64a].forEach(function(o) {
+  var badArrayTypes = [
+    undefined, 1, 'hi', 3.4, ab, u32a, sab, sf32a, sf64a, u8ca
+  ];
+  badArrayTypes.forEach(function(o) {
     assertThrows(function() { Atomics.compareExchange(o, 0, 0, 0); },
                  TypeError);
     assertThrows(function() { Atomics.load(o, 0); }, TypeError);
@@ -129,15 +126,16 @@
 
   var testOp = function(op, ia, index, expectedIndex, name) {
     for (var i = 0; i < ia.length; ++i)
-      ia[i] = 22;
+      ia[i] = i * 2;
 
     ia[expectedIndex] = 0;
-    assertEquals(0, op(ia, index, 0, 0), name);
+    var result = op(ia, index, 0, 0);
+    assertEquals(0, result, name);
     assertEquals(0, ia[expectedIndex], name);
 
     for (var i = 0; i < ia.length; ++i) {
       if (i == expectedIndex) continue;
-      assertEquals(22, ia[i], name);
+      assertEquals(i * 2, ia[i], name);
     }
   };
 
@@ -222,6 +220,24 @@
       }
     })
   });
+
+  // Test Smi range
+  (function () {
+    var sab = new SharedArrayBuffer(4);
+    var i32 = new Int32Array(sab);
+    var u32 = new Uint32Array(sab);
+
+    function testLoad(signedValue, unsignedValue) {
+      u32[0] = unsignedValue;
+      assertEquals(unsignedValue, Atomics.load(u32, 0));
+      assertEquals(signedValue, Atomics.load(i32, 0));
+    }
+
+    testLoad(0x3fffffff,  0x3fffffff); // 2**30-1 (always smi)
+    testLoad(0x40000000,  0x40000000); // 2**30 (smi if signed and 32-bits)
+    testLoad(0x80000000, -0x80000000); // 2**31 (smi if signed and 32-bits)
+    testLoad(0xffffffff, -1);          // 2**31 (smi if signed)
+  });
 })();
 
 (function TestStore() {
@@ -405,7 +421,7 @@
       assertEquals(50, Atomics.compareExchange(sta, 0, v, v), name);
 
       // Store
-      assertEquals(+v, Atomics.store(sta, 0, v), name);
+      assertEquals(v|0, Atomics.store(sta, 0, v), name);
       assertEquals(v|0, sta[0], name);
 
       // Add
diff --git a/test/mjsunit/harmony/do-expressions.js b/test/mjsunit/harmony/do-expressions.js
index b3be4ec..38b68b6 100644
--- a/test/mjsunit/harmony/do-expressions.js
+++ b/test/mjsunit/harmony/do-expressions.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-do-expressions --harmony-sloppy-let --allow-natives-syntax
+// Flags: --harmony-do-expressions --allow-natives-syntax
 
 function returnValue(v) { return v; }
 function MyError() {}
diff --git a/test/mjsunit/harmony/for-in.js b/test/mjsunit/harmony/for-in.js
new file mode 100644
index 0000000..58e343b
--- /dev/null
+++ b/test/mjsunit/harmony/for-in.js
@@ -0,0 +1,9 @@
+// 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-for-in
+
+assertThrows("for (var x = 0 in {});", SyntaxError);
+assertThrows("for (const x = 0 in {});", SyntaxError);
+assertThrows("for (let x = 0 in {});", SyntaxError);
diff --git a/test/mjsunit/harmony/function-sent.js b/test/mjsunit/harmony/function-sent.js
index b3cd644..cd0ca95 100644
--- a/test/mjsunit/harmony/function-sent.js
+++ b/test/mjsunit/harmony/function-sent.js
@@ -49,7 +49,7 @@
     try {
       yield function.sent;
     } finally {
-      return 666;
+      return 23;
     }
   }
 
@@ -77,7 +77,7 @@
     let x = g();
     assertEquals({value: 1, done: false}, x.next(1));
     assertEquals({value: undefined, done: false}, x.next(2));
-    assertEquals({value: 42, done: true}, x.return(42));
+    assertEquals({value: 23, done: true}, x.return(42));
   }
 }
 
diff --git a/test/mjsunit/harmony/generators.js b/test/mjsunit/harmony/generators.js
index df6cec8..895a248 100644
--- a/test/mjsunit/harmony/generators.js
+++ b/test/mjsunit/harmony/generators.js
@@ -2,6 +2,34 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// Flags: --ignition-generators --harmony-do-expressions
+// Flags: --allow-natives-syntax
+
+
+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
 
@@ -9,19 +37,19 @@
     try {yield 1} catch (error) {assertEquals("caught", error)}
   };
 
-  assertThrowsEquals(() => g().throw("not caught"), "not caught");
+  assertThrowsEquals(() => Throw(g(), "not caught"), "not caught");
 
   {
     let x = g();
-    assertEquals({value: 1, done: false}, x.next());
-    assertEquals({value: undefined, done: true}, x.throw("caught"));
+    assertEquals({value: 1, done: false}, Next(x));
+    assertEquals({value: undefined, done: true}, Throw(x, "caught"));
   }
 
   {
     let x = g();
-    assertEquals({value: 1, done: false}, x.next());
-    assertEquals({value: undefined, done: true}, x.next());
-    assertThrowsEquals(() => x.throw("not caught"), "not caught");
+    assertEquals({value: 1, done: false}, Next(x));
+    assertEquals({value: undefined, done: true}, Next(x));
+    assertThrowsEquals(() => Throw(x, "not caught"), "not caught");
   }
 }
 
@@ -31,19 +59,19 @@
 
   {
     let x = g();
-    assertEquals({value: 43, done: false}, x.next());
-    assertEquals({value: 42, done: true}, x.next());
+    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 {x.throw(666)} };
+  let g = function*() { try {return 42} finally {Throw(x, 666)} };
 
   {
     x = g();
-    assertThrows(() => x.next(), TypeError);  // still executing
+    assertThrows(() => Next(x), TypeError);  // still executing
   }
 }
 
@@ -54,42 +82,42 @@
 
   { // "return" closes at suspendedStart
     let x = g();
-    assertEquals({value: 666, done: true}, x.return(666));
-    assertEquals({value: undefined, done: true}, x.next(42));
-    assertThrowsEquals(() => x.throw(43), 43);
-    assertEquals({value: 42, done: true}, x.return(42));
+    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(() => x.throw(666), 666);
-    assertEquals({value: undefined, done: true}, x.next(42));
-    assertEquals({value: 43, done: true}, x.return(43));
-    assertThrowsEquals(() => x.throw(44), 44);
+    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}, x.next());
-    assertEquals({value: 13, done: true}, x.next(666));
-    assertEquals({value: undefined, done: true}, x.next(666));
-    assertThrowsEquals(() => x.throw(666), 666);
+    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}, x.next());
-    assertEquals({value: 13, done: true}, x.return(666));
-    assertEquals({value: undefined, done: true}, x.next(666));
-    assertEquals({value: 666, done: true}, x.return(666));
+    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}, x.next());
-    assertEquals({value: 13, done: true}, x.throw(666));
-    assertThrowsEquals(() => x.throw(666), 666);
-    assertEquals({value: undefined, done: true}, x.next(666));
+    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));
   }
 }
 
@@ -100,45 +128,45 @@
 
   { // "return" closes at suspendedStart
     let x = g();
-    assertEquals({value: 666, done: true}, x.return(666));
-    assertEquals({value: undefined, done: true}, x.next(42));
-    assertThrowsEquals(() => x.throw(43), 43);
-    assertEquals({value: 42, done: true}, x.return(42));
+    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(() => x.throw(666), 666);
-    assertEquals({value: undefined, done: true}, x.next(42));
-    assertEquals({value: 43, done: true}, x.return(43));
-    assertThrowsEquals(() => x.throw(44), 44);
+    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}, x.next());
-    assertEquals({value: undefined, done: true}, x.next(666));
-    assertEquals({value: undefined, done: true}, x.next(666));
-    assertThrowsEquals(() => x.throw(666), 666);
-    assertEquals({value: 42, done: true}, x.return(42));
+    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}, x.next());
-    assertEquals({value: 666, done: true}, x.return(666));
-    assertEquals({value: undefined, done: true}, x.next(666));
-    assertThrowsEquals(() => x.throw(44), 44);
-    assertEquals({value: 42, done: true}, x.return(42));
+    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}, x.next());
-    assertThrowsEquals(() => x.throw(666), 666);
-    assertEquals({value: undefined, done: true}, x.next(666));
-    assertThrowsEquals(() => x.throw(666), 666);
-    assertEquals({value: 42, done: true}, x.return(42));
+    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));
   }
 }
 
@@ -149,17 +177,17 @@
 
   {
     let x = g();
-    assertEquals({value: 42, done: false}, x.next());
-    assertEquals({value: 43, done: false}, x.return(666));
-    assertEquals({value: 13, done: true}, x.next());
-    assertEquals({value: 666, done: true}, x.return(666));
+    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}, x.return(666));
-    assertEquals({value: undefined, done: true}, x.next());
-    assertEquals({value: 666, done: true}, x.return(666));
+    assertEquals({value: 666, done: true}, Return(x, 666));
+    assertEquals({value: undefined, done: true}, Next(x));
+    assertEquals({value: 666, done: true}, Return(x, 666));
   }
 }
 
@@ -170,17 +198,17 @@
 
   {
     let x = g();
-    assertEquals({value: 42, done: false}, x.next());
-    assertEquals({value: 43, done: false}, x.return(666));
-    assertEquals({value: 666, done: true}, x.next());
-    assertEquals({value: 5, done: true}, x.return(5));
+    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}, x.return(666));
-    assertEquals({value: undefined, done: true}, x.next());
-    assertEquals({value: 666, done: true}, x.return(666));
+    assertEquals({value: 666, done: true}, Return(x, 666));
+    assertEquals({value: undefined, done: true}, Next(x));
+    assertEquals({value: 666, done: true}, Return(x, 666));
   }
 }
 
@@ -192,29 +220,29 @@
 
   {
     let x = g();
-    assertEquals({value: 1, done: false}, x.next());
-    assertEquals({value: 42, done: false}, x.next());
-    assertEquals({value: 43, done: false}, x.next(666));
-    assertEquals({value: 13, done: false}, x.next());
-    assertEquals({value: undefined, done: true}, x.next());
+    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}, x.next());
-    assertEquals({value: 42, done: false}, x.next());
-    assertEquals({value: 43, done: false}, x.return(666));
-    assertEquals({value: 13, done: false}, x.next());
-    assertEquals({value: undefined, done: true}, x.next());
+    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}, x.next());
-    assertEquals({value: 42, done: false}, x.next());
-    assertEquals({value: 43, done: false}, x.throw(666));
-    assertEquals({value: 13, done: false}, x.next());
-    assertEquals({value: undefined, done: true}, x.next());
+    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));
   }
 }
 
@@ -226,28 +254,28 @@
 
   {
     let x = g();
-    assertEquals({value: 1, done: false}, x.next());
-    assertEquals({value: 42, done: false}, x.next());
-    assertEquals({value: 43, done: false}, x.next(666));
-    assertEquals({value: undefined, done: false}, x.next());
-    assertEquals({value: undefined, done: true}, x.next());
+    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}, x.next());
-    assertEquals({value: 42, done: false}, x.next());
-    assertEquals({value: 43, done: false}, x.return(44));
-    assertEquals({value: 44, done: false}, x.next());
-    assertEquals({value: undefined, done: true}, x.next());
+    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}, x.next());
-    assertEquals({value: 42, done: false}, x.next());
-    assertEquals({value: 43, done: false}, x.throw(666));
-    assertThrowsEquals(() => x.next(), 666);
+    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);
   }
 }
 
@@ -265,8 +293,370 @@
 
   {
     let x = g();
-    assertEquals({value: 1, done: false}, x.next());
-    assertEquals({value: 2, done: false}, x.next());
-    assertEquals({value: 42, done: true}, x.return(42));
+    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));
+}
+
+{
+  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/harmony-string-pad-end.js b/test/mjsunit/harmony/harmony-string-pad-end.js
index 3292e94..03e5aea 100644
--- a/test/mjsunit/harmony/harmony-string-pad-end.js
+++ b/test/mjsunit/harmony/harmony-string-pad-end.js
@@ -67,8 +67,19 @@
 (function TestFillerToString() {
   assertEquals(".         ", ".".padEnd(10));
   assertEquals(".         ", ".".padEnd(10, undefined));
-  assertEquals(".         ", ".".padEnd(10, { toString() { return ""; } }));
   assertEquals(".nullnulln", ".".padEnd(10, null));
+  assertEquals(".XXXXXXXXX", ".".padEnd(10, { toString() { return "X"; } }));
+  assertEquals(
+      ".111111111",
+      ".".padEnd(10, { toString: undefined, valueOf() { return 1; } }));
+})();
+
+
+(function TestFillerEmptyString() {
+  assertEquals(".", ".".padEnd(10, ""));
+  assertEquals(".", ".".padEnd(10, { toString() { return ""; } }));
+  assertEquals(
+      ".", ".".padEnd(10, { toString: undefined, valueOf() { return ""; } }));
 })();
 
 
diff --git a/test/mjsunit/harmony/harmony-string-pad-start.js b/test/mjsunit/harmony/harmony-string-pad-start.js
index 2b2d004..33bf8f3 100644
--- a/test/mjsunit/harmony/harmony-string-pad-start.js
+++ b/test/mjsunit/harmony/harmony-string-pad-start.js
@@ -67,8 +67,19 @@
 (function TestFillerToString() {
   assertEquals("         .", ".".padStart(10));
   assertEquals("         .", ".".padStart(10, undefined));
-  assertEquals("         .", ".".padStart(10, { toString() { return ""; } }));
   assertEquals("nullnulln.", ".".padStart(10, null));
+  assertEquals("XXXXXXXXX.", ".".padStart(10, { toString() { return "X"; } }));
+  assertEquals(
+      "111111111.",
+      ".".padStart(10, { toString: undefined, valueOf() { return 1; } }));
+})();
+
+
+(function TestFillerEmptyString() {
+  assertEquals(".", ".".padStart(10, ""));
+  assertEquals(".", ".".padStart(10, { toString() { return ""; } }));
+  assertEquals(
+      ".", ".".padStart(10, { toString: undefined, valueOf() { return ""; } }));
 })();
 
 
diff --git a/test/mjsunit/harmony/instanceof-es6.js b/test/mjsunit/harmony/instanceof-es6.js
index 60e7ee2..4971c9c 100644
--- a/test/mjsunit/harmony/instanceof-es6.js
+++ b/test/mjsunit/harmony/instanceof-es6.js
@@ -48,3 +48,22 @@
 
 // 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
index 09e0153..03cdeac 100644
--- a/test/mjsunit/harmony/iterator-close.js
+++ b/test/mjsunit/harmony/iterator-close.js
@@ -1007,6 +1007,26 @@
   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);
 }
 
 
@@ -1051,6 +1071,26 @@
   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);
 }
 
 
@@ -1095,6 +1135,26 @@
   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);
 }
 
 
@@ -1238,3 +1298,75 @@
   }, 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/regexp-property-binary.js b/test/mjsunit/harmony/regexp-property-binary.js
new file mode 100644
index 0000000..d0894b7
--- /dev/null
+++ b/test/mjsunit/harmony/regexp-property-binary.js
@@ -0,0 +1,25 @@
+// 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 --harmony-unicode-regexps
+
+function t(re, s) { assertTrue(re.test(s)); }
+function f(re, s) { assertFalse(re.test(s)); }
+
+t(/\p{Bidi_Control}+/u, "\u200E");
+f(/\p{Bidi_C}+/u, "On a dark desert highway, cool wind in my hair");
+t(/\p{AHex}+/u, "DEADBEEF");
+t(/\p{Alphabetic}+/u, "abcdefg");
+t(/\P{Alphabetic}+/u, "1234");
+t(/\p{White_Space}+/u, "\u00A0");
+t(/\p{Uppercase}+/u, "V");
+f(/\p{Lower}+/u, "U");
+t(/\p{Ideo}+/u, "字");
+f(/\p{Ideo}+/u, "x");
+
+assertThrows("/\\p{Hiragana}/u");
+assertThrows("/\\p{Bidi_Class}/u");
+assertThrows("/\\p{Bidi_C=False}/u");
+assertThrows("/\\P{Bidi_Control=Y}/u");
+assertThrows("/\\p{AHex=Yes}/u");
diff --git a/test/mjsunit/harmony/regexp-property-blocks.js b/test/mjsunit/harmony/regexp-property-blocks.js
index d186e98..f41c06e 100644
--- a/test/mjsunit/harmony/regexp-property-blocks.js
+++ b/test/mjsunit/harmony/regexp-property-blocks.js
@@ -7,28 +7,28 @@
 function t(re, s) { assertTrue(re.test(s)); }
 function f(re, s) { assertFalse(re.test(s)); }
 
-t(/\p{InASCII}+/u, ".");
-t(/\p{InASCII}+/u, "supercalifragilisticexpialidocious");
-t(/\p{InBasic_Latin}+/u, ".");
-t(/\p{InBasic_Latin}+/u, "supercalifragilisticexpialidocious");
+t(/\p{Block=ASCII}+/u, ".");
+t(/\p{Block=ASCII}+/u, "supercalifragilisticexpialidocious");
+t(/\p{Block=Basic_Latin}+/u, ".");
+t(/\p{Block=Basic_Latin}+/u, "supercalifragilisticexpialidocious");
 
-t(/\p{InCJK}+/u, "话说天下大势,分久必合,合久必分");
-t(/\p{InCJK_Unified_Ideographs}+/u, "吾庄后有一桃园,花开正盛");
-f(/\p{InCJK}+/u, "おはようございます");
-f(/\p{InCJK_Unified_Ideographs}+/u,
+t(/\p{blk=CJK}+/u, "话说天下大势,分久必合,合久必分");
+t(/\p{blk=CJK_Unified_Ideographs}+/u, "吾庄后有一桃园,花开正盛");
+f(/\p{blk=CJK}+/u, "おはようございます");
+f(/\p{blk=CJK_Unified_Ideographs}+/u,
   "Something is rotten in the state of Denmark");
 
-t(/\p{InLatin_1}+/u, "Wie froh bin ich, daß ich weg bin!");
-f(/\p{InLatin_1_Supplement}+/u, "奔腾千里荡尘埃,渡水登山紫雾开");
-f(/\p{InLatin_1_Sup}+/u, "いただきます");
+t(/\p{blk=Latin_1}+/u, "Wie froh bin ich, daß ich weg bin!");
+f(/\p{blk=Latin_1_Supplement}+/u, "奔腾千里荡尘埃,渡水登山紫雾开");
+f(/\p{blk=Latin_1_Sup}+/u, "いただきます");
 
-t(/\p{InHiragana}/u, "いただきます");
-t(/\p{Hiragana}/u, "\u{1b001}");    // This refers to the script "Hiragana".
-f(/\p{InHiragana}/u, "\u{1b001}");  // This refers to the block "Hiragana".
+t(/\p{blk=Hiragana}/u, "いただきます");
+t(/\p{sc=Hiragana}/u, "\u{1b001}");   // This refers to the script "Hiragana".
+f(/\p{blk=Hiragana}/u, "\u{1b001}");  // This refers to the block "Hiragana".
 
-t(/\p{InGreek_And_Coptic}/u,
+t(/\p{blk=Greek_And_Coptic}/u,
   "ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ");
-t(/\p{InGreek}/u, "μῆνιν ἄειδε θεὰ Πηληϊάδεω Ἀχιλῆος");
+t(/\p{blk=Greek}/u, "μῆνιν ἄειδε θεὰ Πηληϊάδεω Ἀχιλῆος");
 
 assertThrows("/\\p{In}/u");
 assertThrows("/\\pI/u");
diff --git a/test/mjsunit/harmony/regexp-property-char-class.js b/test/mjsunit/harmony/regexp-property-char-class.js
index 76774cb..6162012 100644
--- a/test/mjsunit/harmony/regexp-property-char-class.js
+++ b/test/mjsunit/harmony/regexp-property-char-class.js
@@ -9,9 +9,6 @@
 assertThrows("/[\\p{}]/u");
 assertThrows("/[\\p{]/u");
 assertThrows("/[\\p}]/u");
-assertThrows("/[\\p{Math}]/u");
-assertThrows("/[\\p{Bidi_M}]/u");
-assertThrows("/[\\p{Hex}]/u");
 
 assertTrue(/^[\p{Lu}\p{Ll}]+$/u.test("ABCabc"));
 assertTrue(/^[\p{Lu}-\p{Ll}]+$/u.test("ABC-abc"));
@@ -19,6 +16,9 @@
 assertTrue(/^[\P{Lu}\p{Ll}]+$/u.test("abc"));
 assertTrue(/^[\P{Lu}]+$/u.test("abc123"));
 assertFalse(/^[\P{Lu}]+$/u.test("XYZ"));
+assertTrue(/[\p{Math}]/u.test("+"));
+assertTrue(/[\P{Bidi_M}]/u.test(" "));
+assertTrue(/[\p{Hex}]/u.test("A"));
 
 assertTrue(/^[^\P{Lu}]+$/u.test("XYZ"));
 assertFalse(/^[^\p{Lu}\p{Ll}]+$/u.test("abc"));
diff --git a/test/mjsunit/harmony/regexp-property-enumerated.js b/test/mjsunit/harmony/regexp-property-enumerated.js
new file mode 100644
index 0000000..e4a81a4
--- /dev/null
+++ b/test/mjsunit/harmony/regexp-property-enumerated.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-regexp-property --harmony-unicode-regexps
+
+function t(re, s) { assertTrue(re.test(s)); }
+function f(re, s) { assertFalse(re.test(s)); }
+
+t(/\p{Bidi_Class=L}+/u, "Is this the real life?");
+t(/\p{bc=Left_To_Right}+/u, "Is this just fantasy?");
+t(/\p{bc=AL}+/u, "السلام عليكم‎");
+t(/\p{bc=Arabic_Letter}+/u, "متشرف بمعرفتك‎");
+
+t(/\p{Line_Break=Glue}/u, "\u00A0");
+t(/\p{lb=AL}/u, "~");
+
+assertThrows("/\\p{Block=}/u");
+assertThrows("/\\p{=}/u");
+assertThrows("/\\p{=L}/u");
+assertThrows("/\\p{=Hiragana}/u");
+assertThrows("/\\p{Block=CJK=}/u");
+
+assertThrows("/\\p{Age=V8_0}/u");
+assertThrows("/\\p{General_Category=Letter}/u");
+assertThrows("/\\p{gc=L}/u");
+assertThrows("/\\p{General_Category_Mask=Letter}/u");
+assertThrows("/\\p{gcm=L}/u");
diff --git a/test/mjsunit/harmony/regexp-property-exact-match.js b/test/mjsunit/harmony/regexp-property-exact-match.js
index 4dfcc5f..fe233f2 100644
--- a/test/mjsunit/harmony/regexp-property-exact-match.js
+++ b/test/mjsunit/harmony/regexp-property-exact-match.js
@@ -6,12 +6,12 @@
 
 assertThrows("/\\p{In CJK}/u");
 assertThrows("/\\p{InCJKUnifiedIdeographs}/u");
-assertDoesNotThrow("/\\p{InCJK}/u");
-assertDoesNotThrow("/\\p{InCJK_Unified_Ideographs}/u");
+assertThrows("/\\p{InCJK}/u");
+assertThrows("/\\p{InCJK_Unified_Ideographs}/u");
 
-assertDoesNotThrow("/\\p{InCyrillic_Sup}/u");
-assertDoesNotThrow("/\\p{InCyrillic_Supplement}/u");
-assertDoesNotThrow("/\\p{InCyrillic_Supplementary}/u");
+assertThrows("/\\p{InCyrillic_Sup}/u");
+assertThrows("/\\p{InCyrillic_Supplement}/u");
+assertThrows("/\\p{InCyrillic_Supplementary}/u");
 assertThrows("/\\p{InCyrillicSupplementary}/u");
 assertThrows("/\\p{InCyrillic_supplementary}/u");
 
@@ -25,9 +25,18 @@
 assertDoesNotThrow("/\\p{Combining_Mark}/u");
 assertThrows("/\\p{Combining Mark}/u");
 
-assertDoesNotThrow("/\\p{Copt}/u");
-assertDoesNotThrow("/\\p{Coptic}/u");
-assertDoesNotThrow("/\\p{Qaac}/u");
-assertDoesNotThrow("/\\p{Egyp}/u");
-assertDoesNotThrow("/\\p{Egyptian_Hieroglyphs}/u");
+assertDoesNotThrow("/\\p{Script=Copt}/u");
+assertThrows("/\\p{Coptic}/u");
+assertThrows("/\\p{Qaac}/u");
+assertThrows("/\\p{Egyp}/u");
+assertDoesNotThrow("/\\p{Script=Egyptian_Hieroglyphs}/u");
 assertThrows("/\\p{EgyptianHieroglyphs}/u");
+
+assertThrows("/\\p{BidiClass=LeftToRight}/u");
+assertThrows("/\\p{BidiC=LeftToRight}/u");
+assertThrows("/\\p{bidi_c=Left_To_Right}/u");
+
+assertDoesNotThrow("/\\p{Block=CJK}/u");
+assertThrows("/\\p{Block = CJK}/u");
+assertThrows("/\\p{Block=cjk}/u");
+assertThrows("/\\p{BLK=CJK}/u");
diff --git a/test/mjsunit/harmony/regexp-property-scripts.js b/test/mjsunit/harmony/regexp-property-scripts.js
index 19b50ee..ec2b11d 100644
--- a/test/mjsunit/harmony/regexp-property-scripts.js
+++ b/test/mjsunit/harmony/regexp-property-scripts.js
@@ -7,33 +7,33 @@
 function t(re, s) { assertTrue(re.test(s)); }
 function f(re, s) { assertFalse(re.test(s)); }
 
-t(/\p{Common}+/u, ".");
-f(/\p{Common}+/u, "supercalifragilisticexpialidocious");
+t(/\p{Script=Common}+/u, ".");
+f(/\p{Script=Common}+/u, "supercalifragilisticexpialidocious");
 
-t(/\p{Han}+/u, "话说天下大势,分久必合,合久必分");
-t(/\p{Hani}+/u, "吾庄后有一桃园,花开正盛");
-f(/\p{Han}+/u, "おはようございます");
-f(/\p{Hani}+/u, "Something is rotten in the state of Denmark");
+t(/\p{Script=Han}+/u, "话说天下大势,分久必合,合久必分");
+t(/\p{Script=Hani}+/u, "吾庄后有一桃园,花开正盛");
+f(/\p{Script=Han}+/u, "おはようございます");
+f(/\p{Script=Hani}+/u, "Something is rotten in the state of Denmark");
 
-t(/\p{Latin}+/u, "Wie froh bin ich, daß ich weg bin!");
-t(/\p{Latn}+/u,
+t(/\p{Script=Latin}+/u, "Wie froh bin ich, daß ich weg bin!");
+t(/\p{Script=Latn}+/u,
   "It was a bright day in April, and the clocks were striking thirteen");
-f(/\p{Latin}+/u, "奔腾千里荡尘埃,渡水登山紫雾开");
-f(/\p{Latn}+/u, "いただきます");
+f(/\p{Script=Latin}+/u, "奔腾千里荡尘埃,渡水登山紫雾开");
+f(/\p{Script=Latn}+/u, "いただきます");
 
-t(/\p{Hiragana}/u, "いただきます");
-t(/\p{Hira}/u, "ありがとうございました");
-f(/\p{Hiragana}/u,
+t(/\p{sc=Hiragana}/u, "いただきます");
+t(/\p{sc=Hira}/u, "ありがとうございました");
+f(/\p{sc=Hiragana}/u,
   "Als Gregor Samsa eines Morgens aus unruhigen Träumen erwachte");
-f(/\p{Hira}/u, "Call me Ishmael");
+f(/\p{sc=Hira}/u, "Call me Ishmael");
 
-t(/\p{Phoenician}/u, "\u{10900}\u{1091a}");
-t(/\p{Phnx}/u, "\u{1091f}\u{10916}");
-f(/\p{Phoenician}/u, "Arthur est un perroquet");
-f(/\p{Phnx}/u, "设心狠毒非良士,操卓原来一路人");
+t(/\p{sc=Phoenician}/u, "\u{10900}\u{1091a}");
+t(/\p{sc=Phnx}/u, "\u{1091f}\u{10916}");
+f(/\p{sc=Phoenician}/u, "Arthur est un perroquet");
+f(/\p{sc=Phnx}/u, "设心狠毒非良士,操卓原来一路人");
 
-t(/\p{Grek}/u, "ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ");
-t(/\p{Greek}/u, "μῆνιν ἄειδε θεὰ Πηληϊάδεω Ἀχιλῆος");
-f(/\p{Greek}/u, "高贤未服英雄志,屈节偏生杰士疑");
-f(/\p{Greek}/u,
+t(/\p{sc=Grek}/u, "ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ");
+t(/\p{sc=Greek}/u, "μῆνιν ἄειδε θεὰ Πηληϊάδεω Ἀχιλῆος");
+f(/\p{sc=Greek}/u, "高贤未服英雄志,屈节偏生杰士疑");
+f(/\p{sc=Greek}/u,
   "Mr. Jones, of the Manor Farm, had locked the hen-houses for the night");
diff --git a/test/mjsunit/harmony/regress/regress-4904.js b/test/mjsunit/harmony/regress/regress-4904.js
new file mode 100644
index 0000000..a57d246
--- /dev/null
+++ b/test/mjsunit/harmony/regress/regress-4904.js
@@ -0,0 +1,24 @@
+// 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-do-expressions
+
+(function testCatchScopeInDoExpression() {
+  var f = (s = 17, y = do { try { throw 25; } catch(e) { s += e; }; }) => s;
+  var result = f();
+  assertEquals(result, 42);
+})();
+
+(function testCatchScopeInDoExpression() {
+  var f = (s = 17, y = do { let t; try { throw 25; } catch(e) { s += e; }; }) => s;
+  var result = f();
+  assertEquals(result, 42);
+})();
+
+(function testCatchScopeInDoExpression() {
+  let t1;
+  var f = (s = 17, y = do { let t2; try { throw 25; } catch(e) { s += e; }; }) => s;
+  var result = f();
+  assertEquals(result, 42);
+})();
diff --git a/test/mjsunit/harmony/regress/regress-observe-empty-double-array.js b/test/mjsunit/harmony/regress/regress-observe-empty-double-array.js
deleted file mode 100644
index 1460889..0000000
--- a/test/mjsunit/harmony/regress/regress-observe-empty-double-array.js
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --harmony-object-observe
-// Flags: --allow-natives-syntax
-//
-// Test passes if it does not crash.
-
-arr = [1.1];
-Object.observe(arr, function(){});
-arr.length = 0;
-// TODO(observe): we currently disallow fast elements for observed object.
-// assertTrue(%HasFastDoubleElements(arr));
-// Should not crash
-arr.push(1.1);
diff --git a/test/mjsunit/holy-double-no-arg-array.js b/test/mjsunit/holy-double-no-arg-array.js
new file mode 100644
index 0000000..73e2ddc
--- /dev/null
+++ b/test/mjsunit/holy-double-no-arg-array.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.
+
+(function() {
+  function f() {
+    return new Array();
+  }
+  var a = f();
+  a[0] = 0.5;
+  var b = f();
+  b[2] = 0.5;
+  assertEquals(undefined, b[0]);
+})();
diff --git a/test/mjsunit/ignition/elided-instruction-no-ignition.js b/test/mjsunit/ignition/elided-instruction-no-ignition.js
index d31150b..50ad528 100644
--- a/test/mjsunit/ignition/elided-instruction-no-ignition.js
+++ b/test/mjsunit/ignition/elided-instruction-no-ignition.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: --expose-debug-as debug
+// Flags: --no-ignition --expose-debug-as debug
 
 Debug = debug.Debug
 
diff --git a/test/mjsunit/ignition/elided-instruction.js b/test/mjsunit/ignition/elided-instruction.js
index 807974b..a047f41 100644
--- a/test/mjsunit/ignition/elided-instruction.js
+++ b/test/mjsunit/ignition/elided-instruction.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: --expose-debug-as debug
+// Flags: --ignition --expose-debug-as debug
 
 Debug = debug.Debug
 
diff --git a/test/mjsunit/ignition/ignition-statistics-extension.js b/test/mjsunit/ignition/ignition-statistics-extension.js
new file mode 100644
index 0000000..43d05c9
--- /dev/null
+++ b/test/mjsunit/ignition/ignition-statistics-extension.js
@@ -0,0 +1,62 @@
+// 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 --trace-ignition-dispatches
+
+assertEquals(typeof getIgnitionDispatchCounters, "function");
+
+var old_dispatch_counters = getIgnitionDispatchCounters();
+
+// Check that old_dispatch_counters is a non-empty object of objects, such that
+// the value of each property in the inner objects is a number.
+
+assertEquals(typeof old_dispatch_counters, "object");
+assertTrue(Object.getOwnPropertyNames(old_dispatch_counters).length > 0);
+for (var source_bytecode in old_dispatch_counters) {
+  var counters_row = old_dispatch_counters[source_bytecode];
+  assertEquals(typeof counters_row, "object");
+  for (var counter in counters_row) {
+    assertEquals(typeof counters_row[counter], "number");
+  }
+}
+
+// Do something
+function f(x) { return x*x; }
+f(42);
+
+var new_dispatch_counters = getIgnitionDispatchCounters();
+
+var old_source_bytecodes = Object.getOwnPropertyNames(old_dispatch_counters);
+var new_source_bytecodes = Object.getOwnPropertyNames(new_dispatch_counters);
+var common_source_bytecodes = new_source_bytecodes.filter(function (name) {
+  return old_source_bytecodes.indexOf(name) > -1;
+});
+
+// Check that the keys on the outer objects are the same
+assertEquals(common_source_bytecodes, old_source_bytecodes);
+assertEquals(common_source_bytecodes, new_source_bytecodes);
+
+common_source_bytecodes.forEach(function (source_bytecode) {
+  var new_counters_row = new_dispatch_counters[source_bytecode];
+  var old_counters_row = old_dispatch_counters[source_bytecode];
+
+  var old_destination_bytecodes = Object.getOwnPropertyNames(old_counters_row);
+  var new_destination_bytecodes = Object.getOwnPropertyNames(new_counters_row);
+
+  // Check that all the keys in old_ are in new_ too
+  old_destination_bytecodes.forEach(function (name) {
+    assertTrue(new_destination_bytecodes.indexOf(name) > -1);
+  });
+
+  // Check that for each source-destination pair, the counter has either
+  // appeared (was undefined before calling f()), is unchanged, or incremented.
+  new_destination_bytecodes.forEach(function (destination_bytecode) {
+    var new_counter = new_counters_row[destination_bytecode];
+    var old_counter = old_counters_row[destination_bytecode];
+    assertTrue(typeof new_counter === "number");
+    if (typeof old_counter === "number") {
+      assertTrue(new_counter >= old_counter);
+    }
+  });
+});
diff --git a/test/mjsunit/ignition/regress-599001-verifyheap.js b/test/mjsunit/ignition/regress-599001-verifyheap.js
index 5aa2efd..ce5b46d 100644
--- a/test/mjsunit/ignition/regress-599001-verifyheap.js
+++ b/test/mjsunit/ignition/regress-599001-verifyheap.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: --verify-heap --expose-gc
+// Flags: --ignition --verify-heap --expose-gc
 
 // Tests that verify heap works for BytecodeArrays in the large object space.
 
diff --git a/test/mjsunit/messages.js b/test/mjsunit/messages.js
index 8796d05..d40994d 100644
--- a/test/mjsunit/messages.js
+++ b/test/mjsunit/messages.js
@@ -147,7 +147,12 @@
 }, "Method Set.prototype.add called on incompatible receiver [object Array]",
 TypeError);
 
-// kInstanceofFunctionExpected
+// kNonCallableInInstanceOfCheck
+test(function() {
+  1 instanceof {};
+}, "Right-hand side of 'instanceof' is not callable", TypeError);
+
+// kNonObjectInInstanceOfCheck
 test(function() {
   1 instanceof 1;
 }, "Right-hand side of 'instanceof' is not an object", TypeError);
diff --git a/test/mjsunit/migrations.js b/test/mjsunit/migrations.js
index a18d884..2bd70fb 100644
--- a/test/mjsunit/migrations.js
+++ b/test/mjsunit/migrations.js
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-ayle license that can be
 // found in the LICENSE file.
 
-// Flags: --harmony-object-observe
 // Flags: --allow-natives-syntax --track-fields --expose-gc
 
 var global = Function('return this')();
@@ -275,10 +274,6 @@
     },
   },
   {
-    name: "observe",
-    migr: function(o, i) { Object.observe(o, function(){}); },
-  },
-  {
     name: "seal",
     migr: function(o, i) { Object.seal(o); },
   },
diff --git a/test/mjsunit/mirror-object.js b/test/mjsunit/mirror-object.js
index 834d7a5..cae652a 100644
--- a/test/mjsunit/mirror-object.js
+++ b/test/mjsunit/mirror-object.js
@@ -265,3 +265,27 @@
 assertTrue("[[BoundArgs]]" in property_map);
 assertEquals("object", property_map["[[BoundArgs]]"].value().type());
 assertEquals(1, property_map["[[BoundArgs]]"].value().value().length);
+
+// Test JSProxy internal properties.
+var target = {};
+var handler = {
+  get: function (target, name, receiver) {
+    return target[name];
+  },
+  set: function(target, name, value, receiver) {
+    target[name] = value;
+    return value;
+  }
+}
+ip = debug.ObjectMirror.GetInternalProperties(new Proxy(target, handler));
+assertEquals(3, ip.length);
+var property_map = {};
+for (var i = 0; i < ip.length; i++) {
+  property_map[ip[i].name()] = ip[i];
+}
+assertTrue("[[Target]]" in property_map);
+assertEquals(target, property_map["[[Target]]"].value().value());
+assertTrue("[[Handler]]" in property_map);
+assertEquals(handler, property_map["[[Handler]]"].value().value());
+assertTrue("[[IsRevoked]]" in property_map);
+assertEquals(false, property_map["[[IsRevoked]]"].value().value());
diff --git a/test/mjsunit/mjsunit.gyp b/test/mjsunit/mjsunit.gyp
index 35ce2ff..e0a7469 100644
--- a/test/mjsunit/mjsunit.gyp
+++ b/test/mjsunit/mjsunit.gyp
@@ -13,8 +13,8 @@
             '../../src/d8.gyp:d8_run',
           ],
           'includes': [
-            '../../build/features.gypi',
-            '../../build/isolate.gypi',
+            '../../gypfiles/features.gypi',
+            '../../gypfiles/isolate.gypi',
           ],
           'sources': [
             'mjsunit.isolate',
diff --git a/test/mjsunit/mjsunit.js b/test/mjsunit/mjsunit.js
index 9b07953..6a7c2da 100644
--- a/test/mjsunit/mjsunit.js
+++ b/test/mjsunit/mjsunit.js
@@ -114,6 +114,9 @@
 var assertOptimized;
 var assertUnoptimized;
 
+// Assert that a string contains another expected substring.
+var assertContains;
+
 
 (function () {  // Scope for utility functions.
 
@@ -416,6 +419,12 @@
     throw new MjsUnitAssertionError(message);
   };
 
+  assertContains = function(sub, value, name_opt) {
+    if (value == null ? (sub != null) : value.indexOf(sub) == -1) {
+      fail("contains '" + String(sub) + "'", value, name_opt);
+    }
+  };
+
   var OptimizationStatusImpl = undefined;
 
   var OptimizationStatus = function(fun, sync_opt) {
diff --git a/test/mjsunit/mjsunit.status b/test/mjsunit/mjsunit.status
index 6d786f9..228832b 100644
--- a/test/mjsunit/mjsunit.status
+++ b/test/mjsunit/mjsunit.status
@@ -76,6 +76,7 @@
   'unicode-test': [PASS, NO_VARIANTS],
   'whitespaces': [PASS, NO_VARIANTS],
   'compiler/osr-assert': [PASS, NO_VARIANTS],
+  'ignition/regress-599001-verifyheap': [PASS, NO_VARIANTS],
   'es6/string-fromcodepoint': [PASS, NO_VARIANTS],
   'regress/regress-2185-2': [PASS, NO_VARIANTS],
   'regress/regress-2612': [PASS, NO_VARIANTS],
@@ -149,10 +150,6 @@
   # issue 4078:
   'allocation-site-info': [PASS, NO_VARIANTS],
 
-  # TODO(turbofan): The escape analysis needs some investigation.
-  'compiler/escape-analysis-deopt-5': [PASS, NO_VARIANTS],
-  'compiler/escape-analysis-9': [PASS, NO_VARIANTS],
-
   ##############################################################################
   # Too slow in debug mode with --stress-opt mode.
   'compiler/regress-stacktrace-methods': [PASS, ['mode == debug', SKIP]],
@@ -260,7 +257,6 @@
   # Slow tests.
   'copy-on-write-assert': [PASS, SLOW],
   'debug-scopes': [PASS, SLOW],
-  'es7/object-observe': [PASS, ['mode == debug', SLOW]],
   'numops-fuzz-part*': [PASS, ['mode == debug', SLOW]],
   'readonly': [PASS, SLOW],
   'regress/regress-1200351': [PASS, ['mode == debug', SLOW]],
@@ -274,21 +270,72 @@
   'wasm/asm-wasm-literals': [PASS, ['arch in [arm, arm64, mips, mipsel, mips64, mips64el] or ignition == True', SKIP]],
   'wasm/asm-wasm-copy': [PASS, ['arch in [arm, arm64, mips, mipsel, mips64, mips64el]', SKIP]],
   'wasm/asm-wasm-deopt': [PASS, ['arch in [arm, arm64, mips, mipsel, mips64, mips64el]', SKIP]],
+  'wasm/asm-wasm-switch': [PASS, ['arch in [arm, arm64, mips, mipsel, mips64, mips64el]', SKIP]],
 
   # TODO(branelson): Figure out why ignition + asm->wasm fails embenchen.
   'wasm/embenchen/*': [PASS, ['arch == arm64', SKIP], ['ignition == True', SKIP]],
 
-  # TODO(bradnelson) Fix and re-enable.
-  'wasm/embenchen/box2d': [SKIP],   # hang
-  'wasm/embenchen/lua_binarytrees': [SKIP],  # fails decode
-  #'wasm/embenchen/zlib': [SKIP],  # fails gc-stress
-
   # case-insensitive unicode regexp relies on case mapping provided by ICU.
   'harmony/unicode-regexp-ignore-case': [PASS, ['no_i18n == True', FAIL]],
   'harmony/unicode-regexp-ignore-case-noi18n': [FAIL, ['no_i18n == True', PASS]],
   'regress/regress-5036': [PASS, ['no_i18n == True', FAIL]],
   # desugaring regexp property class relies on ICU.
   'harmony/regexp-property-*': [PASS, ['no_i18n == True', FAIL]],
+
+  ############################################################################
+  # Ignition
+
+  # TODO(mythria, 4780): Related to type feedback for calls in interpreter.
+  'array-literal-feedback': [PASS, NO_IGNITION],
+  'regress/regress-4121': [PASS, NO_IGNITION],
+
+  # TODO(mythria, 4764): lack of osr support.
+  'regress/regress-2618': [PASS, NO_IGNITION],
+
+  # TODO(mythria, 4764): lack of osr support. The tests waits in a loop
+  # till it is optimized. So test timeouts.
+  'array-literal-transitions': [PASS, NO_IGNITION],
+
+  # TODO(rmcilroy, 4680): Script throws RangeError as expected, but does so during
+  # eager compile of the whole script instead of during lazy compile of the function
+  # f(), so we can't catch the exception in the try/catch. Skip because on some
+  # platforms the stack limit is different and the exception doesn't fire.
+  'regress/regress-crbug-589472': [PASS, NO_IGNITION],
+
+  # TODO(4680): Test doesn't know about three tier compiler pipeline.
+  'assert-opt-and-deopt': [PASS, NO_IGNITION],
+
+  # BUG(rmcilroy,4989): Function is optimized without type feedback and so immediately deopts again, causing check failure in the test.
+  'compiler/deopt-inlined-from-call': [PASS, NO_IGNITION],
+  'compiler/increment-typefeedback': [PASS, NO_IGNITION],
+  'compiler/manual-concurrent-recompile': [PASS, NO_IGNITION],
+  'constant-folding-2': [PASS, NO_IGNITION],
+  'debug-is-active': [PASS, NO_IGNITION],
+  'deopt-with-fp-regs': [PASS, NO_IGNITION],
+  'deserialize-optimize-inner': [PASS, NO_IGNITION],
+  'div-mul-minus-one': [PASS, NO_IGNITION],
+  'double-intrinsics': [PASS, NO_IGNITION],
+  'elements-transition-hoisting': [PASS, NO_IGNITION],
+  'es6/block-let-crankshaft': [PASS, NO_IGNITION],
+  'es6/block-let-crankshaft-sloppy': [PASS, NO_IGNITION],
+  'getters-on-elements': [PASS, NO_IGNITION],
+  'harmony/do-expressions': [PASS, NO_IGNITION],
+  'math-floor-of-div-minus-zero': [PASS, NO_IGNITION],
+  'regress/regress-2132': [PASS, NO_IGNITION],
+  'regress/regress-2339': [PASS, NO_IGNITION],
+  'regress/regress-3176': [PASS, NO_IGNITION],
+  'regress/regress-3709': [PASS, NO_IGNITION],
+  'regress/regress-385565': [PASS, NO_IGNITION],
+  'regress/regress-crbug-594183': [PASS, NO_IGNITION],
+  'regress/regress-embedded-cons-string': [PASS, NO_IGNITION],
+  'regress/regress-map-invalidation-2': [PASS, NO_IGNITION],
+  'regress/regress-param-local-type': [PASS, NO_IGNITION],
+  'regress/regress-prepare-break-while-recompile': [PASS, NO_IGNITION],
+  'shift-for-integer-div': [PASS, NO_IGNITION],
+  'sin-cos': [PASS, NO_IGNITION],
+  'smi-mul-const': [PASS, NO_IGNITION],
+  'smi-mul': [PASS, NO_IGNITION],
+  'unary-minus-deopt': [PASS, NO_IGNITION],
 }],  # ALWAYS
 
 ['novfp3 == True', {
@@ -459,6 +506,13 @@
   'unicodelctest': [PASS, SLOW],
   'unicode-test': [PASS, SLOW],
   'whitespaces': [PASS, TIMEOUT, SLOW],
+
+  # TODO(rmcilroy,4680): Arm64 specific timeouts.
+  'asm/construct-double': [PASS, NO_IGNITION],
+  'compiler/osr-one': [PASS, NO_IGNITION],
+  'compiler/osr-two': [PASS, NO_IGNITION],
+  'wasm/asm-wasm-i32': [PASS, NO_IGNITION],
+  'wasm/asm-wasm-u32': [PASS, NO_IGNITION],
 }],  # 'arch == arm64'
 
 ['arch == arm64 and mode == debug and simulator_run == True', {
@@ -475,6 +529,11 @@
   'unicodelctest-no-optimization': [PASS, TIMEOUT],
   # Issue 3219:
   'getters-on-elements': [PASS, ['gc_stress == True', FAIL]],
+
+  # Ignition.
+  'es6/templates': [PASS, ['no_snap and mode == debug', NO_IGNITION]],
+  'harmony/generators': [PASS, ['no_snap and mode == debug', NO_IGNITION]],
+  'regress/regress-crbug-364374': [PASS, ['no_snap and mode == debug', NO_IGNITION]],
 }],  # 'arch == arm64 and mode == debug and simulator_run == True'
 
 ##############################################################################
@@ -497,6 +556,17 @@
   'deep-recursion': [SKIP],
   'regress/regress-builtinbust-7': [SKIP],
   'string-localecompare': [SKIP],
+
+  # TODO(mythria,4680): All of these tests have large loops and hence slow
+  # and timeout.
+  'compiler/osr-big': [PASS, NO_IGNITION],
+  'compiler/osr-nested': [PASS, NO_IGNITION],
+  'regress/regress-298269': [PASS, NO_IGNITION],
+  'regress/regress-crbug-319860': [PASS, NO_IGNITION],
+  'regress/regress-deep-proto': [PASS, NO_IGNITION],
+  'try': [PASS, NO_IGNITION],
+  # Too slow for interpreter and msan.
+  'es6/tail-call-megatest*': [PASS, NO_IGNITION],
 }],  # 'msan == True'
 
 ##############################################################################
@@ -542,6 +612,11 @@
   'regress/regress-91008': [PASS, SLOW],
   'regress/regress-json-stringify-gc': [PASS, SLOW],
   'string-indexof-2': [PASS, TIMEOUT],
+
+  # TODO(rmcilroy,4680): Arm specific timeouts.
+  'compiler/osr-one': [PASS, NO_IGNITION],
+  'compiler/osr-two': [PASS, NO_IGNITION],
+  'regress/regress-1257': [PASS, NO_IGNITION],
 }],  # 'arch == arm or arch == android_arm'
 
 ##############################################################################
@@ -759,35 +834,14 @@
 }],  # 'arch == ppc and simulator_run == True'
 
 ##############################################################################
-['ignition == True', {
-  # TODO(yangguo,4690): assertion failures in debugger tests.
-  'debug-allscopes-on-debugger': [FAIL],
-  'es6/debug-stepnext-for': [FAIL],
-  'es6/debug-promises/stepin-constructor': [FAIL],
-  'es6/debug-stepin-proxies': [FAIL],
-  'regress/regress-crbug-119800': [FAIL],
-  'regress/regress-opt-after-debug-deopt': [FAIL],
+['arch == ppc64', {
 
-  # TODO(yangguo,4690): flaky failures on the bots.
-  'debug-stepin-builtin-callback-opt': [SKIP],
+  # stack overflow
+  'big-array-literal': [SKIP],
+}],  # 'arch == ppc64'
 
-   # TODO(rmcilroy,4765): assertion failures in LiveEdit tests.
-  'debug-liveedit-restart-frame': [FAIL],
-  'debug-liveedit-literals': [FAIL],
-  'debug-liveedit-3': [FAIL],
-  'debug-liveedit-1': [FAIL],
-  'debug-liveedit-2': [FAIL],
-  'debug-liveedit-patch-positions-replace': [FAIL],
-  'debug-liveedit-patch-positions': [FAIL],
-  'debug-liveedit-stepin': [FAIL],
-  'debug-liveedit-newsource': [FAIL],
-  'debug-liveedit-stack-padding': [FAIL],
-  'debug-liveedit-breakpoints': [FAIL],
-  'es6/debug-liveedit-new-target-1': [FAIL],
-  'es6/debug-liveedit-new-target-2': [FAIL],
-  'es6/debug-liveedit-new-target-3': [FAIL],
-  'es6/generators-debug-liveedit': [FAIL],
-
+##############################################################################
+['ignition or ignition_turbofan', {
   # TODO(mythria, 4780): Related to type feedback for calls in interpreter.
   'array-literal-feedback': [FAIL],
   'regress/regress-4121': [FAIL],
@@ -798,56 +852,37 @@
   # till it is optimized. So test timeouts.
   'array-literal-transitions': [SKIP],
 
-  # TODO(mythria, 4680): Relate to GC and ignition holding references to
-  # objects.
-  'es6/mirror-collections': [FAIL],
-
-  # TODO(mythria, 4680): Fails with context_register_count_ > 0 (0 vs. 0) when
-  # trying to get a context register in BytecodeGenerator.
-  'harmony/regress/regress-4658': [FAIL, ['mode == release and dcheck_always_on == False', PASS],],
-
   # TODO(rmcilroy, 4680): Script throws RangeError as expected, but does so during
   # eager compile of the whole script instead of during lazy compile of the function
   # f(), so we can't catch the exception in the try/catch. Skip because on some
   # platforms the stack limit is different and the exception doesn't fire.
   'regress/regress-crbug-589472': [SKIP],
 
-  # Debugger test cases that pass with ignition, but not full-codegen.
-  # These differences between full-codegen and ignition are deliberate.
-  'ignition/elided-instruction-no-ignition': [FAIL],
-
   'wasm/asm-wasm-f32': [PASS, ['arch in [arm64]', SKIP]],
   'wasm/asm-wasm-f64': [PASS, ['arch in [arm64]', SKIP]],
-}],  # ignition == True
 
-['ignition == True and system == windows', {
-  # TODO(rmcilroy,4680): Crash on windows nosnap shared.
-  'regress/regress-crbug-352058': [PASS, ['no_snap == True', SKIP]],
+  # TODO(rmcilroy,titzer): Times out after
+  # https://codereview.chromium.org/1951013002 .
+  'regress/regress-599717': [PASS, ['tsan', SKIP]],
+}],  # ignition or ignition_turbofan
 
-  # TODO(513471): Attempting to optimize generator hits unreachable path.
-  'regress/regress-crbug-513471': [PASS, ['no_snap == True', SKIP]],
-
-  # TODO(rmcilroy,4680): Fails on win32 debug.
-  'div-mod': [PASS, ['arch == ia32', SKIP]],
-}],  # ignition == True and system == windows
-
-['ignition == True and arch == arm64', {
+['(ignition or ignition_turbofan) and arch == arm64', {
   # TODO(rmcilroy,4680): Arm64 specific timeouts.
   'asm/construct-double': [SKIP],
   'compiler/osr-one': [SKIP],
   'compiler/osr-two': [SKIP],
   'wasm/asm-wasm-i32': [SKIP],
   'wasm/asm-wasm-u32': [SKIP],
-}],  # ignition == True and arch == arm64
+}],  # (ignition or ignition_turbofan) and arch == arm64
 
-['ignition == True and arch == arm', {
+['(ignition or ignition_turbofan) and arch == arm', {
   # TODO(rmcilroy,4680): Arm specific timeouts.
   'compiler/osr-one': [SKIP],
   'compiler/osr-two': [SKIP],
   'regress/regress-1257': [SKIP],
-}],  # ignition == True and arch == arm
+}],  # (ignition or ignition_turbofan) and arch == arm
 
-['ignition == True and msan', {
+['(ignition or ignition_turbofan) and msan', {
   # TODO(mythria,4680): All of these tests have large loops and hence slow
   # and timeout.
   'compiler/osr-big': [SKIP],
@@ -858,55 +893,7 @@
   'try': [SKIP],
   # Too slow for interpreter and msan.
   'es6/tail-call-megatest*': [SKIP],
-}],  # ignition == True and msan
-
-['ignition == True and gc_stress == True', {
-  # TODO(oth,4680): failures from the bots.
-  'es6/debug-step-destructuring-bind': [SKIP],
-  'es6/debug-stepin-collections-foreach': [SKIP],
-  'ignition/elided-instruction': [SKIP],
-  'regress/regress-269': [SKIP],
-}],  # ignition == True and gc_stress == True
-
-['ignition == False', {
-  # Debugger test cases that pass with full-codegen, but not ignition.
-  # These differences between full-codegen and ignition are deliberate.
-  'ignition/elided-instruction': [FAIL],
-}],  # ignition == False
-
-['ignition == True and system == windows and no_snap', {
-  # TODO(rmcilroy): Fail with nosnap and shared libraries.
-  'es6/array-from': [FAIL],
-  'es6/classes-subclass-builtins': [FAIL],
-  'es6/computed-property-names-classes': [FAIL],
-  'es6/computed-property-names-object-literals-methods': [FAIL],
-  'es6/debug-stepin-generators': [FAIL],
-  'es6/destructuring': [FAIL],
-  'es6/destructuring-assignment': [FAIL],
-  'es6/generators-iteration': [FAIL],
-  'es6/generators-mirror': [FAIL],
-  'es6/generators-parsing': [FAIL],
-  'es6/generators-poisoned-properties': [FAIL],
-  'es6/generators-relocation': [FAIL],
-  'es6/generators-states': [FAIL],
-  'es6/iteration-semantics': [FAIL],
-  'es6/object-literals-method': [FAIL],
-  'es6/object-literals-super': [FAIL],
-  'es6/promises': [FAIL],
-  'es6/regress/regress-2681': [FAIL],
-  'es6/regress/regress-2691': [FAIL],
-  'es6/regress/regress-3280': [FAIL],
-  'es6/spread-array': [FAIL],
-  'es6/spread-call': [FAIL],
-  'es6/typedarray': [FAIL],
-  'es6/typedarray-from': [FAIL],
-  'harmony/function-sent': [FAIL],
-  'harmony/generators': [FAIL],
-  'harmony/iterator-close': [FAIL],
-  'harmony/regress/regress-4482': [FAIL],
-  'messages': [FAIL],
-  'regress-3225': [FAIL],
-}],  # ignition == True and system == windows and no_snap
+}],  # (ignition or ignition_turbofan) and msan
 
 ##############################################################################
 ['gcov_coverage', {
diff --git a/test/mjsunit/object-define-property.js b/test/mjsunit/object-define-property.js
index 4c495c6..380a71a 100644
--- a/test/mjsunit/object-define-property.js
+++ b/test/mjsunit/object-define-property.js
@@ -467,8 +467,7 @@
 }
 
 
-// Test runtime calls to DefineDataPropertyUnchecked and
-// DefineAccessorPropertyUnchecked - make sure we don't
+// Test runtime calls to DefineAccessorPropertyUnchecked - make sure we don't
 // crash.
 try {
   %DefineAccessorPropertyUnchecked(0, 0, 0, 0, 0);
@@ -477,29 +476,11 @@
 }
 
 try {
-  %DefineDataPropertyUnchecked(0, 0, 0, 0);
-} catch (e) {
-  assertTrue(/illegal access/.test(e));
-}
-
-try {
-  %DefineDataPropertyUnchecked(null, null, null, null);
-} catch (e) {
-  assertTrue(/illegal access/.test(e));
-}
-
-try {
   %DefineAccessorPropertyUnchecked(null, null, null, null, null);
 } catch (e) {
   assertTrue(/illegal access/.test(e));
 }
 
-try {
-  %DefineDataPropertyUnchecked({}, null, null, null);
-} catch (e) {
-  assertTrue(/illegal access/.test(e));
-}
-
 // Defining properties null should fail even when we have
 // other allowed values
 try {
@@ -508,12 +489,6 @@
   assertTrue(/illegal access/.test(e));
 }
 
-try {
-  %DefineDataPropertyUnchecked(null, 'foo', 0, 0);
-} catch (e) {
-  assertTrue(/illegal access/.test(e));
-}
-
 // Test that all possible differences in step 6 in DefineOwnProperty are
 // exercised, i.e., any difference in the given property descriptor and the
 // existing properties should not return true, but throw an error if the
diff --git a/test/mjsunit/osr-elements-kind.js b/test/mjsunit/osr-elements-kind.js
index bd15ef3..aee7017 100644
--- a/test/mjsunit/osr-elements-kind.js
+++ b/test/mjsunit/osr-elements-kind.js
@@ -30,7 +30,7 @@
 // Limit the number of stress runs to reduce polymorphism it defeats some of the
 // assumptions made about how elements transitions work because transition stubs
 // end up going generic.
-// Flags: --stress-runs=2
+// Flags: --stress-runs=1
 
 var elements_kind = {
   fast_smi_only             :  'fast smi only elements',
diff --git a/test/mjsunit/regexp-compile.js b/test/mjsunit/regexp-compile.js
index 92c3f7b..f001780 100644
--- a/test/mjsunit/regexp-compile.js
+++ b/test/mjsunit/regexp-compile.js
@@ -42,3 +42,7 @@
 assertEquals(["y", "y"], re.exec("axyb"));
 
 assertEquals(2, re.compile.length);
+
+// If RegExp parsing fails, the RegExp is not modified
+var r = /./; try { r.compile('? invalid'); } catch(err){}
+assertEquals("/./", r.toString());
diff --git a/test/mjsunit/regexp-lastIndex.js b/test/mjsunit/regexp-lastIndex.js
deleted file mode 100644
index 1445b9b..0000000
--- a/test/mjsunit/regexp-lastIndex.js
+++ /dev/null
@@ -1,18 +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.
-
-// lastIndex is set according to funny rules. It is typically set only
-// for global or sticky RegExps, but on a failure to find a match, it is
-// set unconditionally. If a set fails, then it acts as if in strict mode
-// and throws.
-
-var re = /x/;
-Object.defineProperty(re, 'lastIndex', {writable: false});
-assertThrows(() => re.exec(""), TypeError);
-assertEquals(["x"], re.exec("x"));
-
-var re = /x/y;
-Object.defineProperty(re, 'lastIndex', {writable: false});
-assertThrows(() => re.exec(""), TypeError);
-assertThrows(() => re.exec("x"), TypeError);
diff --git a/test/mjsunit/regress-604044.js b/test/mjsunit/regress-604044.js
new file mode 100644
index 0000000..58ccfbe
--- /dev/null
+++ b/test/mjsunit/regress-604044.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.
+
+// Flags: --min-preparse-length 1
+
+(function(_ = function() {}){})
diff --git a/test/mjsunit/regress/regress-3315.js b/test/mjsunit/regress/regress-3315.js
deleted file mode 100644
index bfd7df2..0000000
--- a/test/mjsunit/regress/regress-3315.js
+++ /dev/null
@@ -1,28 +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.
-//
-// Flags: --harmony-object-observe
-
-var indexZeroCallCount = 0;
-var indexOneCallCount = 0;
-var lengthCallCount = 0;
-var acceptList = {
-  get 0() {
-    indexZeroCallCount++;
-    return 'foo';
-  },
-  get 1() {
-    indexOneCallCount++;
-    return 'bar';
-  },
-  get length() {
-    lengthCallCount++;
-    return 1;
-  }
-};
-
-Object.observe({}, function(){}, acceptList);
-assertEquals(1, lengthCallCount);
-assertEquals(1, indexZeroCallCount);
-assertEquals(0, indexOneCallCount);
diff --git a/test/mjsunit/regress/regress-353004.js b/test/mjsunit/regress/regress-353004.js
index 658fd6d..7e1fb7e 100644
--- a/test/mjsunit/regress/regress-353004.js
+++ b/test/mjsunit/regress/regress-353004.js
@@ -41,19 +41,21 @@
 
 
 var buffer5 = new ArrayBuffer(100 * 1024);
-var buffer6 = buffer5.slice({valueOf : function() {
-  %ArrayBufferNeuter(buffer5);
-  return 0;
-}}, 100 * 1024 * 1024);
-assertEquals(0, buffer6.byteLength);
+assertThrows(function() {
+  buffer5.slice({valueOf : function() {
+    %ArrayBufferNeuter(buffer5);
+    return 0;
+  }}, 100 * 1024 * 1024);
+}, TypeError);
 
 
 var buffer7 = new ArrayBuffer(100 * 1024 * 1024);
-var buffer8 = buffer7.slice(0, {valueOf : function() {
-  %ArrayBufferNeuter(buffer7);
-  return 100 * 1024 * 1024;
-}});
-assertEquals(0, buffer8.byteLength);
+assertThrows(function() {
+  buffer7.slice(0, {valueOf : function() {
+    %ArrayBufferNeuter(buffer7);
+    return 100 * 1024 * 1024;
+  }});
+}, TypeError);
 
 var buffer9 = new ArrayBuffer(1024);
 var array9 = new Uint8Array(buffer9);
diff --git a/test/mjsunit/regress/regress-356589.js b/test/mjsunit/regress/regress-356589.js
deleted file mode 100644
index a47f51b..0000000
--- a/test/mjsunit/regress/regress-356589.js
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --harmony-object-observe
-
-// This test passes if it does not crash in debug mode
-
-arr = ['a', 'b', 'c', 'd'];
-Object.defineProperty(arr.__proto__, '0', { get: function(){} });
-Object.defineProperty(arr, '2', {get: function(){} });
-Object.observe(arr, function() {});
-arr.length = 2;
diff --git a/test/mjsunit/regress/regress-3926.js b/test/mjsunit/regress/regress-3926.js
index 4720c1b..4d9b298 100644
--- a/test/mjsunit/regress/regress-3926.js
+++ b/test/mjsunit/regress/regress-3926.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-sloppy --harmony-sloppy-let
-
 // See: http://code.google.com/p/v8/issues/detail?id=3926
 
 // Switch statements should disable hole check elimination
diff --git a/test/mjsunit/regress/regress-417709a.js b/test/mjsunit/regress/regress-417709a.js
deleted file mode 100644
index 5500be2..0000000
--- a/test/mjsunit/regress/regress-417709a.js
+++ /dev/null
@@ -1,17 +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.
-
-// Flags: --harmony-object-observe
-// Flags: --stack-size=100
-
-var a = [];
-
-Object.observe(a, function() {});
-
-function f(a, x) {
-  a.length = x;
-  f(a, x + 1);
-}
-
-assertThrows(function() { f(a, 1); }, RangeError);
diff --git a/test/mjsunit/regress/regress-417709b.js b/test/mjsunit/regress/regress-417709b.js
deleted file mode 100644
index 4d9572e..0000000
--- a/test/mjsunit/regress/regress-417709b.js
+++ /dev/null
@@ -1,16 +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.
-
-// Flags: --harmony-object-observe --stack-size=100
-
-var a = [];
-
-Array.observe(a, function() {});
-
-function f(a, x) {
-  a.length = x;
-  f(a, x + 1);
-}
-
-assertThrows(function() { f(a, 1); }, RangeError);
diff --git a/test/mjsunit/regress/regress-4693.js b/test/mjsunit/regress/regress-4693.js
index 13b4e2b..2c31cd9 100644
--- a/test/mjsunit/regress/regress-4693.js
+++ b/test/mjsunit/regress/regress-4693.js
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
-// Flags: --harmony-sloppy-function
 
 // In sloppy mode we allow function redeclarations within blocks for webcompat.
 (function() {
diff --git a/test/mjsunit/regress/regress-4908.js b/test/mjsunit/regress/regress-4908.js
new file mode 100644
index 0000000..ec618b3
--- /dev/null
+++ b/test/mjsunit/regress/regress-4908.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.
+//
+// Flags: --always-opt --no-lazy
+
+(function() { ((s = 17, y = s) => s)() })();
diff --git a/test/mjsunit/regress/regress-4945.js b/test/mjsunit/regress/regress-4945.js
new file mode 100644
index 0000000..8e595e6
--- /dev/null
+++ b/test/mjsunit/regress/regress-4945.js
@@ -0,0 +1,10 @@
+// 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* g(o) {
+  yield 'x' in o;
+}
+
+assertTrue(g({x: 1}).next().value);
+assertFalse(g({}).next().value);
diff --git a/test/mjsunit/regress/regress-4964.js b/test/mjsunit/regress/regress-4964.js
new file mode 100644
index 0000000..d834708
--- /dev/null
+++ b/test/mjsunit/regress/regress-4964.js
@@ -0,0 +1,22 @@
+// 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: --allow-natives-syntax
+
+// Neutered source
+var ab = new ArrayBuffer(10);
+ab.constructor = { get [Symbol.species]() { %ArrayBufferNeuter(ab); return ArrayBuffer; } };
+assertThrows(() => ab.slice(0), TypeError);
+
+// Neutered target
+class NeuteredArrayBuffer extends ArrayBuffer {
+  constructor(...args) {
+    super(...args);
+    %ArrayBufferNeuter(this);
+  }
+}
+
+var ab2 = new ArrayBuffer(10);
+ab2.constructor = NeuteredArrayBuffer;
+assertThrows(() => ab2.slice(0), TypeError);
diff --git a/test/mjsunit/regress/regress-4967.js b/test/mjsunit/regress/regress-4967.js
new file mode 100644
index 0000000..9b36405
--- /dev/null
+++ b/test/mjsunit/regress/regress-4967.js
@@ -0,0 +1,9 @@
+// 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.
+
+assertThrows(() => {
+  new class extends Object {
+    constructor() { (() => delete super[super()])(); }
+  }
+}, ReferenceError);
diff --git a/test/mjsunit/regress/regress-4971.js b/test/mjsunit/regress/regress-4971.js
new file mode 100644
index 0000000..041f6c2
--- /dev/null
+++ b/test/mjsunit/regress/regress-4971.js
@@ -0,0 +1,41 @@
+// 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: --allow-natives-syntax
+
+(function TestDeoptInNamedSuperGetter() {
+  class C { m() { return 23 } }
+  class D extends C { f() { return super.boom() } }
+
+  var should_deoptimize_caller = false;
+  Object.defineProperty(C.prototype, "boom", { get: function() {
+    if (should_deoptimize_caller) %DeoptimizeFunction(D.prototype.f);
+    return this.m
+  }})
+
+  assertEquals(23, new D().f());
+  assertEquals(23, new D().f());
+  %OptimizeFunctionOnNextCall(D.prototype.f);
+  assertEquals(23, new D().f());
+  should_deoptimize_caller = true;
+  assertEquals(23, new D().f());
+})();
+
+(function TestDeoptInKeyedSuperGetter() {
+  class C { m() { return 23 } }
+  class D extends C { f(name) { return super[name]() } }
+
+  var should_deoptimize_caller = false;
+  Object.defineProperty(C.prototype, "boom", { get: function() {
+    if (should_deoptimize_caller) %DeoptimizeFunction(D.prototype.f);
+    return this.m
+  }})
+
+  assertEquals(23, new D().f("boom"));
+  assertEquals(23, new D().f("boom"));
+  %OptimizeFunctionOnNextCall(D.prototype.f);
+  assertEquals(23, new D().f("boom"));
+  should_deoptimize_caller = true;
+  assertEquals(23, new D().f("boom"));
+})();
diff --git a/test/mjsunit/regress/regress-5033.js b/test/mjsunit/regress/regress-5033.js
new file mode 100644
index 0000000..728094f
--- /dev/null
+++ b/test/mjsunit/regress/regress-5033.js
@@ -0,0 +1,21 @@
+// 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: --allow-natives-syntax
+
+var test = function() {
+  var t = Date.now();  // Just any non-constant double value.
+  var o = {
+    ['p']: 1,
+    t
+  };
+};
+
+function caller() {
+  test();
+}
+caller();
+caller();
+%OptimizeFunctionOnNextCall(caller);
+caller();
diff --git a/test/mjsunit/regress/regress-5178.js b/test/mjsunit/regress/regress-5178.js
new file mode 100644
index 0000000..bc0dd11
--- /dev/null
+++ b/test/mjsunit/regress/regress-5178.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.
+
+assertThrows(() => {
+  try { throw {} } catch({a=b, b}) { a+b }
+}, ReferenceError);
diff --git a/test/mjsunit/regress/regress-5199.js b/test/mjsunit/regress/regress-5199.js
new file mode 100644
index 0000000..818e71a
--- /dev/null
+++ b/test/mjsunit/regress/regress-5199.js
@@ -0,0 +1,5 @@
+// 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.
+
+assertTrue(/(a[\u1000A])+/i.test('aa'));
diff --git a/test/mjsunit/regress/regress-520029.js b/test/mjsunit/regress/regress-520029.js
index 299dd75..9a1d200 100644
--- a/test/mjsunit/regress/regress-520029.js
+++ b/test/mjsunit/regress/regress-520029.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-sloppy-let --harmony-sloppy
-
 // Test that hoisting a function out of a lexical scope does not
 // lead to a parsing error
 
diff --git a/test/mjsunit/regress/regress-536751.js b/test/mjsunit/regress/regress-536751.js
index 0707e00..a63fae3 100644
--- a/test/mjsunit/regress/regress-536751.js
+++ b/test/mjsunit/regress/regress-536751.js
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Flags: --harmony-sloppy --harmony-sloppy-function --harmony-sloppy-let
 // Flags: --no-harmony-restrictive-declarations
 
 // At some point, this code led to DCHECK errors in debug mode
diff --git a/test/mjsunit/regress/regress-542099.js b/test/mjsunit/regress/regress-542099.js
index eef4953..6345fd4 100644
--- a/test/mjsunit/regress/regress-542099.js
+++ b/test/mjsunit/regress/regress-542099.js
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Flags: --harmony-sloppy --harmony-sloppy-function
 // Flags: --no-harmony-restrictive-declarations
 
 // Previously, this caused a CHECK fail in debug mode
diff --git a/test/mjsunit/regress/regress-542100.js b/test/mjsunit/regress/regress-542100.js
index 70fb5dc..c16e628 100644
--- a/test/mjsunit/regress/regress-542100.js
+++ b/test/mjsunit/regress/regress-542100.js
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Flags: --harmony-sloppy --harmony-sloppy-function
 // Flags: --no-harmony-restrictive-declarations
 
 (function() {
diff --git a/test/mjsunit/regress/regress-585041.js b/test/mjsunit/regress/regress-585041.js
new file mode 100644
index 0000000..c072ed2
--- /dev/null
+++ b/test/mjsunit/regress/regress-585041.js
@@ -0,0 +1,21 @@
+// 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: --allow-natives-syntax
+
+function f(arr, i) {
+  arr[i] = 50;
+}
+
+function boom(dummy) {
+  var arr = new Array(10);
+  f(arr, 10);
+  if (dummy) {
+    f(arr, -2147483648);
+  }
+}
+
+boom(false);
+%OptimizeFunctionOnNextCall(boom);
+boom(false);
diff --git a/test/mjsunit/regress/regress-592352.js b/test/mjsunit/regress/regress-592352.js
new file mode 100644
index 0000000..f3477c0
--- /dev/null
+++ b/test/mjsunit/regress/regress-592352.js
@@ -0,0 +1,20 @@
+// 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-wasm --allow-natives-syntax
+
+function __f_76() {
+  "use asm";
+  function __f_72() {
+    %OptimizeFunctionOnNextCall();
+  }
+  return {__f_72:__f_72};
+}
+
+try {
+  Wasm.instantiateModuleFromAsm( __f_76.toString());
+  assertTrue(false);
+} catch (e) {
+  print("Caught: " + e);
+}
diff --git a/test/mjsunit/regress/regress-599068-func-bindings.js b/test/mjsunit/regress/regress-599068-func-bindings.js
new file mode 100644
index 0000000..887c000
--- /dev/null
+++ b/test/mjsunit/regress/regress-599068-func-bindings.js
@@ -0,0 +1,45 @@
+// 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: --allow-natives-syntax
+
+// Tests function bindings are correctly handled in ignition.
+(function f() {
+  function assignSloppy() {
+    f = 0;
+  }
+  assertDoesNotThrow(assignSloppy);
+
+  function assignStrict() {
+    'use strict';
+    f = 0;
+  }
+  assertThrows(assignStrict, TypeError);
+
+  function assignStrictLookup() {
+    eval("'use strict'; f = 1;");
+  }
+  assertThrows(assignStrictLookup, TypeError);
+})();
+
+// Tests for compound assignments which are handled differently
+// in crankshaft.
+(function f() {
+  function assignSloppy() {
+    f += "x";
+  }
+  assertDoesNotThrow(assignSloppy);
+  assertDoesNotThrow(assignSloppy);
+  %OptimizeFunctionOnNextCall(assignSloppy);
+  assertDoesNotThrow(assignSloppy);
+
+  function assignStrict() {
+    'use strict';
+    f += "x";
+  }
+  assertThrows(assignStrict, TypeError);
+  assertThrows(assignStrict, TypeError);
+  %OptimizeFunctionOnNextCall(assignStrict);
+  assertThrows(assignStrict, TypeError);
+})();
diff --git a/test/mjsunit/regress/regress-599717.js b/test/mjsunit/regress/regress-599717.js
new file mode 100644
index 0000000..2cfd7fc
--- /dev/null
+++ b/test/mjsunit/regress/regress-599717.js
@@ -0,0 +1,25 @@
+// 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-wasm
+
+function __f_61(stdlib, buffer) {
+  "use asm";
+  var __v_14 = new stdlib.Float64Array(buffer);
+  function __f_74() {
+    var __v_35 = 6.0;
+    __v_14[2] = __v_35 + 1.0;
+  }
+  return {__f_74: __f_74};
+}
+var ok = false;
+try {
+  var __v_12 = new ArrayBuffer(2147483648);
+  ok = true;
+} catch (e) {
+  // Can happen on 32 bit systems.
+}
+if (ok) {
+  var module = Wasm.instantiateModuleFromAsm( __f_61.toString(), null, __v_12);
+}
diff --git a/test/mjsunit/regress/regress-599719.js b/test/mjsunit/regress/regress-599719.js
new file mode 100644
index 0000000..579fa1f
--- /dev/null
+++ b/test/mjsunit/regress/regress-599719.js
@@ -0,0 +1,24 @@
+// 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: --allow-natives-syntax --expose-wasm
+
+function __f_7() {
+    %DeoptimizeFunction(__f_5);
+}
+function __f_8(global, env) {
+  "use asm";
+  var __f_7 = env.__f_7;
+  function __f_9(i4, i5) {
+    i4 = i4 | 0;
+    i5 = i5 | 0;
+    __f_7();
+  }
+  return {'__f_9': __f_9}
+}
+function __f_5() {
+  var __v_5 = Wasm.instantiateModuleFromAsm( __f_8.toString(), {'__f_7': __f_7});
+  __v_5.__f_9(0, 0, 0);
+}
+__f_5();
diff --git a/test/mjsunit/regress/regress-605470.js b/test/mjsunit/regress/regress-605470.js
new file mode 100644
index 0000000..722e8ae
--- /dev/null
+++ b/test/mjsunit/regress/regress-605470.js
@@ -0,0 +1,17 @@
+// 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
+
+function function_with_m_args(m) {
+  var source = '(function f() { return; })(';
+  for (var arg = 0; arg < m ; arg++) {
+    if (arg != 0) source += ',';
+    source += arg;
+  }
+  source += ')';
+  return eval(source);
+}
+
+function_with_m_args(0x7FFF);
diff --git a/test/mjsunit/regress/regress-605488.js b/test/mjsunit/regress/regress-605488.js
new file mode 100644
index 0000000..03e6a38
--- /dev/null
+++ b/test/mjsunit/regress/regress-605488.js
@@ -0,0 +1,12 @@
+// 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-wasm
+
+try {
+  Wasm.instantiateModuleFromAsm("");
+  assertTrue(false);
+} catch (e) {
+  print("Caught: " + e);
+}
diff --git a/test/mjsunit/regress/regress-606021.js b/test/mjsunit/regress/regress-606021.js
new file mode 100644
index 0000000..54b283e
--- /dev/null
+++ b/test/mjsunit/regress/regress-606021.js
@@ -0,0 +1,32 @@
+// 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: --allow-natives-syntax
+
+function foo() {
+  return function(c) {
+    var double_var = [3.0, 3.5][0];
+    var literal = c ? [1, double_var] : [double_var, 3.5];
+    return literal[0];
+  };
+}
+
+var f1 = foo();
+var f2 = foo();
+
+// Both closures point to full code.
+f1(false);
+f2(false);
+
+// Optimize f1, but don't initialize the [1, double_var] literal.
+%OptimizeFunctionOnNextCall(f1);
+f1(false);
+
+// Initialize the [1, double_var] literal, and transition the boilerplate to
+// double.
+f2(true);
+
+// Trick crankshaft into writing double_var at the wrong position.
+var l = f1(true);
+assertEquals(1, l);
diff --git a/test/mjsunit/regress/regress-608630.js b/test/mjsunit/regress/regress-608630.js
new file mode 100644
index 0000000..a0f3c43
--- /dev/null
+++ b/test/mjsunit/regress/regress-608630.js
@@ -0,0 +1,69 @@
+// 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-wasm
+
+var __v_5 = {};
+var __v_35 = {};
+var __v_44 = {};
+var __v_43 = {};
+
+try {
+__v_1 = 1;
+__v_2 = {
+  get: function() { return function() {} },
+  has() { return true },
+  getOwnPropertyDescriptor: function() {
+    if (__v_1-- == 0) throw "please die";
+    return {value: function() {}, configurable: true};
+  }
+};
+__v_3 = new Proxy({}, __v_2);
+__v_30 = Object.create(__v_35);
+with (__v_5) { f() }
+} catch(e) { print("Caught: " + e); }
+
+function __f_1(asmfunc, expect) {
+  var __v_1 = asmfunc.toString();
+  var __v_2 = __v_1.replace(new RegExp("use asm"), "");
+  var __v_39 = {Math: Math};
+  var __v_4 = eval("(" + __v_2 + ")")(__v_3);
+  print("Testing " + asmfunc.name + " (js)...");
+  __v_44.valueOf = __v_43;
+  expect(__v_4);
+  print("Testing " + asmfunc.name + " (asm.js)...");
+  var __v_5 = asmfunc(__v_3);
+  expect(__v_5);
+  print("Testing " + asmfunc.name + " (wasm)...");
+  var __v_6 = Wasm.instantiateModuleFromAsm(__v_1, __v_3);
+  expect(__v_6);
+}
+function __f_2() {
+  "use asm";
+  function __f_3() { return 0; }
+  function __f_4() { return 1; }
+  function __f_5() { return 4; }
+  function __f_6() { return 64; }
+  function __f_7() { return 137; }
+  function __f_8() { return 128; }
+  function __f_9() { return -1; }
+  function __f_10() { return 1000; }
+  function __f_11() { return 2000000; }
+  function __f_12() { return 2147483647; }
+  return {__f_3: __f_3, __f_4: __f_4, __f_5: __f_5, __f_6: __f_6, __f_7: __f_7, __f_8: __f_8,
+          __f_9: __f_9, __f_10: __f_10, __f_11, __f_12: __f_12};
+}
+try {
+__f_1(__f_2, function(module) {
+  assertEquals(0, module.__f_3());
+  assertEquals(1, module.__f_4());
+  assertEquals(4, module.__f_5());
+  assertEquals(64, module.__f_6());
+  assertEquals(128, module.__f_8());
+  assertEquals(-1, module.__f_9());
+  assertEquals(1000, module.__f_10());
+  assertEquals(2000000, module.__f_11());
+  assertEquals(2147483647, module.__f_12());
+});
+} catch(e) { print("Caught: " + e); }
diff --git a/test/mjsunit/regress/regress-610633.js b/test/mjsunit/regress/regress-610633.js
new file mode 100644
index 0000000..8ee0e7e
--- /dev/null
+++ b/test/mjsunit/regress/regress-610633.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.
+
+function getLength(a) {
+  return a.length;
+}
+
+function getByteLength(a) {
+  return a.byteLength;
+}
+
+function getByteOffset(a) {
+  return a.byteOffset;
+}
+
+var a = new Uint8Array([1, 2, 3]);
+getLength(a);
+getLength(a);
+
+Object.defineProperty(a.__proto__, 'length', {value: 42});
+
+assertEquals(42, getLength(a));
+assertEquals(42, a.length);
+
+getByteLength(a);
+getByteLength(a);
+
+Object.defineProperty(a.__proto__, 'byteLength', {value: 42});
+
+assertEquals(42, getByteLength(a));
+assertEquals(42, a.byteLength);
+
+getByteOffset(a);
+getByteOffset(a);
+
+Object.defineProperty(a.__proto__, 'byteOffset', {value: 42});
+
+assertEquals(42, getByteOffset(a));
+assertEquals(42, a.byteOffset);
diff --git a/test/mjsunit/regress/regress-616386.js b/test/mjsunit/regress/regress-616386.js
new file mode 100644
index 0000000..d462ab7
--- /dev/null
+++ b/test/mjsunit/regress/regress-616386.js
@@ -0,0 +1,10 @@
+// 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-lazy
+
+assertEquals(0, ((y = (function(a2) { bbbb = a2 }), bbbb = eval('1')) => {y(0); return bbbb})())
+assertEquals(0, (({y = (function(a2) { bbbb = a2 }), bbbb = eval('1')} = {}) => {y(0); return bbbb})())
+assertEquals(0, (function (y = (function(a2) { bbbb = a2 }), bbbb = eval('1')) {y(0); return bbbb})())
+assertEquals(0, (function ({y = (function(a2) { bbbb = a2 }), bbbb = eval('1')} = {}) {y(0); return bbbb})())
diff --git a/test/mjsunit/regress/regress-619382.js b/test/mjsunit/regress/regress-619382.js
new file mode 100644
index 0000000..971318a
--- /dev/null
+++ b/test/mjsunit/regress/regress-619382.js
@@ -0,0 +1,35 @@
+// 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-gc --always-opt
+
+(function __f_9() {
+})();
+function __f_16(ctor_desc) {
+  var __v_22 = 5;
+  var __v_25 = [];
+  gc(); gc(); gc();
+  for (var __v_18 = 0; __v_18 < __v_22; __v_18++) {
+    __v_25[__v_18] = ctor_desc.ctor.apply();
+  }
+}
+var __v_28 = [
+  {
+    ctor: function(__v_27) { return {a: __v_27}; },
+    args: function() { return [1.5 + __v_18]; }  },
+  {
+    ctor: function(__v_27) { var __v_21 = []; __v_21[1] = __v_27; __v_21[200000] = __v_27; return __v_21; },
+    args: function() { return [1.5 + __v_18]; }  },
+  {
+    ctor: function() {
+    }  }
+];
+var __v_26 = [
+  {
+  }];
+  __v_26.forEach(function(__v_16) {
+    __v_28.forEach(function(ctor) {
+      __f_16(ctor);
+    });
+  });
diff --git a/test/mjsunit/regress/regress-620553.js b/test/mjsunit/regress/regress-620553.js
new file mode 100644
index 0000000..461b9bb
--- /dev/null
+++ b/test/mjsunit/regress/regress-620553.js
@@ -0,0 +1,17 @@
+// 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-gc
+
+var o0 = [];
+var o1 = [];
+var cnt = 0;
+o1.__defineGetter__(0, function() {
+  if (cnt++ > 2) return;
+  o0.shift();
+  gc();
+  o0.push(0);
+  o0.concat(o1);
+});
+o1[0];
diff --git a/test/mjsunit/regress/regress-621869.js b/test/mjsunit/regress/regress-621869.js
new file mode 100644
index 0000000..db34064
--- /dev/null
+++ b/test/mjsunit/regress/regress-621869.js
@@ -0,0 +1,18 @@
+// 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-gc
+
+var o0 = [];
+var o1 = [];
+var cnt = 0;
+var only_scavenge = true;
+o1.__defineGetter__(0, function() {
+  if (cnt++ > 2) return;
+  o0.shift();
+  gc(only_scavenge);
+  o0.push((64));
+  o0.concat(o1);
+});
+o1[0];
diff --git a/test/mjsunit/regress/regress-674753.js b/test/mjsunit/regress/regress-674753.js
index b3704ea..d8a504a 100644
--- a/test/mjsunit/regress/regress-674753.js
+++ b/test/mjsunit/regress/regress-674753.js
@@ -25,62 +25,138 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+// Flags: --allow-natives-syntax
+
+var undetectable = %GetUndetectable();
+
 // Number
 assertTrue(typeof 0 == 'number');
 assertTrue(typeof 0 === 'number');
+assertFalse(typeof 0 != 'number');
+assertFalse(typeof 0 !== 'number');
 assertTrue(typeof 1.2 == 'number');
 assertTrue(typeof 1.2 === 'number');
+assertFalse(typeof 1.2 != 'number');
+assertFalse(typeof 1.2 !== 'number');
+assertTrue(typeof 'x' != 'number');
+assertTrue(typeof 'x' !== 'number');
 assertFalse(typeof 'x' == 'number');
 assertFalse(typeof 'x' === 'number');
+assertTrue(typeof Object() != 'number');
+assertTrue(typeof Object() !== 'number');
+assertFalse(typeof Object() == 'number');
+assertFalse(typeof Object() === 'number');
 
 // String
 assertTrue(typeof 'x' == 'string');
 assertTrue(typeof 'x' === 'string');
+assertFalse(typeof 'x' != 'string');
+assertFalse(typeof 'x' !== 'string');
 assertTrue(typeof ('x' + 'x') == 'string');
 assertTrue(typeof ('x' + 'x') === 'string');
+assertFalse(typeof ('x' + 'x') != 'string');
+assertFalse(typeof ('x' + 'x') !== 'string');
+assertTrue(typeof 1 != 'string');
+assertTrue(typeof 1 !== 'string');
 assertFalse(typeof 1 == 'string');
 assertFalse(typeof 1 === 'string');
+assertTrue(typeof Object() != 'string');
+assertTrue(typeof Object() !== 'string');
 assertFalse(typeof Object() == 'string');
 assertFalse(typeof Object() === 'string');
 
 // Boolean
 assertTrue(typeof true == 'boolean');
 assertTrue(typeof true === 'boolean');
+assertFalse(typeof true != 'boolean');
+assertFalse(typeof true !== 'boolean');
 assertTrue(typeof false == 'boolean');
 assertTrue(typeof false === 'boolean');
+assertFalse(typeof false != 'boolean');
+assertFalse(typeof false !== 'boolean');
+assertTrue(typeof 1 != 'boolean');
+assertTrue(typeof 1 !== 'boolean');
 assertFalse(typeof 1 == 'boolean');
 assertFalse(typeof 1 === 'boolean');
+assertTrue(typeof 'x' != 'boolean');
+assertTrue(typeof 'x' !== 'boolean');
+assertFalse(typeof 'x' == 'boolean');
+assertFalse(typeof 'x' === 'boolean');
+assertTrue(typeof Object() != 'boolean');
+assertTrue(typeof Object() !== 'boolean');
 assertFalse(typeof Object() == 'boolean');
 assertFalse(typeof Object() === 'boolean');
 
 // Undefined
 assertTrue(typeof void 0 == 'undefined');
 assertTrue(typeof void 0 === 'undefined');
+assertFalse(typeof void 0 != 'undefined');
+assertFalse(typeof void 0 !== 'undefined');
+assertTrue(typeof 1 != 'undefined');
+assertTrue(typeof 1 !== 'undefined');
 assertFalse(typeof 1 == 'undefined');
 assertFalse(typeof 1 === 'undefined');
+assertTrue(typeof null != 'undefined');
+assertTrue(typeof null !== 'undefined');
+assertFalse(typeof null == 'undefined');
+assertFalse(typeof null === 'undefined');
+assertTrue(typeof Object() != 'undefined');
+assertTrue(typeof Object() !== 'undefined');
 assertFalse(typeof Object() == 'undefined');
 assertFalse(typeof Object() === 'undefined');
+assertTrue(typeof undetectable == 'undefined');
+assertTrue(typeof undetectable === 'undefined');
+assertFalse(typeof undetectable != 'undefined');
+assertFalse(typeof undetectable !== 'undefined');
 
 // Function
 assertTrue(typeof Object == 'function');
 assertTrue(typeof Object === 'function');
+assertFalse(typeof Object != 'function');
+assertFalse(typeof Object !== 'function');
+assertTrue(typeof 1 != 'function');
+assertTrue(typeof 1 !== 'function');
 assertFalse(typeof 1 == 'function');
 assertFalse(typeof 1 === 'function');
+assertTrue(typeof Object() != 'function');
+assertTrue(typeof Object() !== 'function');
 assertFalse(typeof Object() == 'function');
 assertFalse(typeof Object() === 'function');
+assertTrue(typeof undetectable != 'function');
+assertTrue(typeof undetectable !== 'function');
+assertFalse(typeof undetectable == 'function');
+assertFalse(typeof undetectable === 'function');
 
 // Object
 assertTrue(typeof Object() == 'object');
 assertTrue(typeof Object() === 'object');
+assertFalse(typeof Object() != 'object');
+assertFalse(typeof Object() !== 'object');
 assertTrue(typeof new String('x') == 'object');
 assertTrue(typeof new String('x') === 'object');
+assertFalse(typeof new String('x') != 'object');
+assertFalse(typeof new String('x') !== 'object');
 assertTrue(typeof ['x'] == 'object');
 assertTrue(typeof ['x'] === 'object');
+assertFalse(typeof ['x'] != 'object');
+assertFalse(typeof ['x'] !== 'object');
 assertTrue(typeof null == 'object');
 assertTrue(typeof null === 'object');
+assertFalse(typeof null != 'object');
+assertFalse(typeof null !== 'object');
+assertTrue(typeof 1 != 'object');
+assertTrue(typeof 1 !== 'object');
 assertFalse(typeof 1 == 'object');
 assertFalse(typeof 1 === 'object');
+assertTrue(typeof 'x' != 'object');
+assertTrue(typeof 'x' !== 'object');
 assertFalse(typeof 'x' == 'object');  // bug #674753
 assertFalse(typeof 'x' === 'object');
+assertTrue(typeof Object != 'object');
+assertTrue(typeof Object !== 'object');
 assertFalse(typeof Object == 'object');
 assertFalse(typeof Object === 'object');
+assertTrue(typeof undetectable != 'object');
+assertTrue(typeof undetectable !== 'object');
+assertFalse(typeof undetectable == 'object');
+assertFalse(typeof undetectable === 'object');
diff --git a/test/mjsunit/regress/regress-crbug-119800.js b/test/mjsunit/regress/regress-crbug-119800.js
index 3946fbb..85f28a7 100644
--- a/test/mjsunit/regress/regress-crbug-119800.js
+++ b/test/mjsunit/regress/regress-crbug-119800.js
@@ -5,9 +5,9 @@
 // Flags: --expose-debug-as debug
 
 function f() {
-  1;
-  2;
-  3;
+  print(1);
+  print(2);
+  print(3);
 }
 
 var Debug = debug.Debug;
@@ -34,4 +34,5 @@
 Debug.debuggerFlags().breakPointsActive.setValue(true);
 
 assertNull(exception);
-assertEquals(breaks, ["1;", "2;", "3;", "}", "Debug.setListener(null);"]);
+assertEquals(breaks, ["print(1);", "print(2);", "print(3);", "}",
+                      "Debug.setListener(null);"]);
diff --git a/test/mjsunit/regress/regress-crbug-451770.js b/test/mjsunit/regress/regress-crbug-451770.js
index 770c807..b4f088d 100644
--- a/test/mjsunit/regress/regress-crbug-451770.js
+++ b/test/mjsunit/regress/regress-crbug-451770.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-sloppy
-
 assertThrows(function f() {
   var t = { toString: function() { throw new Error(); } };
   var o = { [t]: 23 };
diff --git a/test/mjsunit/regress/regress-crbug-480807.js b/test/mjsunit/regress/regress-crbug-480807.js
index c273f20..a1448d6 100644
--- a/test/mjsunit/regress/regress-crbug-480807.js
+++ b/test/mjsunit/regress/regress-crbug-480807.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: --allow-natives-syntax --use-osr --turbo-osr --noalways-opt
+// Flags: --allow-natives-syntax --use-osr --noalways-opt
 
 function foo() {
   var c = 0;
diff --git a/test/mjsunit/regress/regress-crbug-582048.js b/test/mjsunit/regress/regress-crbug-582048.js
new file mode 100644
index 0000000..6d98f48
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-582048.js
@@ -0,0 +1,31 @@
+// 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
+
+var Debug = debug.Debug;
+
+function listener(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    var frame_count = exec_state.frameCount();
+    for (var i = 0; i < frame_count; i++) {
+      var frame = exec_state.frame(i);
+      var scope_count = frame.scopeCount();
+      for (var j = 0; j < scope_count; j++) {
+        var scope = frame.scope(j);
+        assertTrue(scope.scopeObject().property('').isUndefined());
+      }
+    }
+  } catch (e) {
+    print(e, e.stack);
+    exception = e;
+  }
+}
+
+Debug.setListener(listener);
+
+(function(a = 1) { debugger; })();
+
+Debug.setListener(null);
diff --git a/test/mjsunit/regress/regress-crbug-600257.js b/test/mjsunit/regress/regress-crbug-600257.js
new file mode 100644
index 0000000..87bd2e3
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-600257.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: --stack-size=100
+
+(function rec() {
+  try {
+    rec();
+  } catch (e) {
+    /{/;
+  }
+})();
diff --git a/test/mjsunit/regress/regress-crbug-602184.js b/test/mjsunit/regress/regress-crbug-602184.js
new file mode 100644
index 0000000..c7d793b
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-602184.js
@@ -0,0 +1,17 @@
+// 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 f(test, a) {
+  var v;
+  if (test) {
+    v = v|0;
+  }
+  a[v] = 1;
+}
+var v = new String();
+f(false, v);
+f(false, v);
+
+v = new Int32Array(10);
+f(true, v);
diff --git a/test/mjsunit/regress/regress-crbug-602595.js b/test/mjsunit/regress/regress-crbug-602595.js
new file mode 100644
index 0000000..7f6d478
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-602595.js
@@ -0,0 +1,12 @@
+// 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: --allow-natives-syntax --turbo-escape
+
+function f(a) { return [a] }
+
+assertEquals([23], f(23));
+assertEquals([42], f(42));
+%OptimizeFunctionOnNextCall(f);
+assertEquals([65], f(65));
diff --git a/test/mjsunit/regress/regress-crbug-603463.js b/test/mjsunit/regress/regress-crbug-603463.js
new file mode 100644
index 0000000..20bfae6
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-603463.js
@@ -0,0 +1,16 @@
+// 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 load(a, i) {
+  return a[i];
+}
+
+function f() {
+  return load(new Proxy({}, {}), undefined);
+}
+
+f();
+f();
+load([11, 22, 33], 0);
+f();
diff --git a/test/mjsunit/regress/regress-crbug-604299.js b/test/mjsunit/regress/regress-crbug-604299.js
new file mode 100644
index 0000000..9908f2d
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-604299.js
@@ -0,0 +1,9 @@
+// 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.
+
+Array.prototype.__defineSetter__(0,function(value){});
+
+if (this.Intl) {
+  var o = new Intl.DateTimeFormat('en-US', {'timeZone': 'Asia/Katmandu'})
+}
diff --git a/test/mjsunit/regress/regress-crbug-605060.js b/test/mjsunit/regress/regress-crbug-605060.js
new file mode 100644
index 0000000..d2dc79a
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-605060.js
@@ -0,0 +1,10 @@
+// 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: --allow-natives-syntax
+
+Array.prototype.__defineGetter__('map', function(){});
+Array.prototype.__defineGetter__('map', function(){});
+Array.prototype.__defineGetter__('map', function(){});
+assertTrue(%HasFastProperties(Array.prototype));
diff --git a/test/mjsunit/regress/regress-crbug-605581.js b/test/mjsunit/regress/regress-crbug-605581.js
new file mode 100644
index 0000000..0f1daab
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-605581.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: --expose-debug-as debug
+
+var Debug = debug.Debug;
+var exception = null;
+
+function listener(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    assertThrows(() => exec_state.frame(0).evaluate("bar.baz"), ReferenceError);
+  } catch (e) {
+    exception = e;
+  }
+}
+
+Debug.setListener(listener);
+
+(function() {
+  debugger;    // bar is still in TDZ at this point.
+  let bar = 1;
+  (x => bar);  // force bar to be context-allocated.
+})();
+
+Debug.setListener(null);
+assertNull(exception);
diff --git a/test/mjsunit/regress/regress-crbug-605862.js b/test/mjsunit/regress/regress-crbug-605862.js
new file mode 100644
index 0000000..3124c06
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-605862.js
@@ -0,0 +1,8 @@
+// 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
+
+/[]*1/u.exec("\u1234");
+/[^\u0000-\u{10ffff}]*1/u.exec("\u1234");
diff --git a/test/mjsunit/regress/regress-crbug-608279.js b/test/mjsunit/regress/regress-crbug-608279.js
new file mode 100644
index 0000000..22c69f2
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-608279.js
@@ -0,0 +1,18 @@
+// 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: --always-opt --no-lazy
+
+function __f_38() {
+  try {
+    throw 0;
+  } catch (e) {
+    eval();
+    var __v_38 = { a: 'hest' };
+    __v_38.m = function () { return __v_38.a; };
+  }
+  return __v_38;
+}
+var __v_40 = __f_38();
+__v_40.m();
diff --git a/test/mjsunit/regress/regress-crbug-609029.js b/test/mjsunit/regress/regress-crbug-609029.js
new file mode 100644
index 0000000..bd77de2
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-609029.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.
+
+// Flags: --always-opt --function-context-specialization --gc-interval=14
+// Flags: --turbo-filter=match --verify-heap
+"xxx".match();
diff --git a/test/mjsunit/regress/regress-crbug-609046.js b/test/mjsunit/regress/regress-crbug-609046.js
new file mode 100644
index 0000000..10b63af
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-609046.js
@@ -0,0 +1,36 @@
+// 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
+
+// Test that hidden scopes are correctly walked in the scope chain.
+
+var Debug = debug.Debug;
+var exception = null;
+var delegate = null;
+var done = false;
+
+function listener(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    assertEquals([ debug.ScopeType.Block,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global ],
+                 exec_state.frame(0).allScopes().map(s => s.scopeType()));
+    done = true;
+  } catch (e) {
+    exception = e;
+  }
+}
+
+Debug.setListener(listener);
+
+for(let a = 0; a < 3; a++) {
+  debugger;
+  eval();  // Force context-allocation of everything.
+}
+
+Debug.setListener(null);
+assertNull(exception);
+assertTrue(done);
diff --git a/test/mjsunit/regress/regress-crbug-610207.js b/test/mjsunit/regress/regress-crbug-610207.js
new file mode 100644
index 0000000..4396a56
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-610207.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.
+
+Error.prepareStackTrace = function(exception, frames) {
+  return frames[0].getEvalOrigin();
+}
+
+try {
+  Realm.eval(0, "throw new Error('boom');");
+} catch(e) {
+  print(e.stack);
+}
diff --git a/test/mjsunit/regress/regress-crbug-610228.js b/test/mjsunit/regress/regress-crbug-610228.js
deleted file mode 100644
index ca077d5..0000000
--- a/test/mjsunit/regress/regress-crbug-610228.js
+++ /dev/null
@@ -1,11 +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: --allow-natives-syntax
-
-function foo() { return JSON.stringify({a: 0.1}); }
-assertEquals('{"a":0.1}', foo());
-assertEquals('{"a":0.1}', foo());
-%OptimizeFunctionOnNextCall(foo);
-assertEquals('{"a":0.1}', foo());
diff --git a/test/mjsunit/regress/regress-crbug-612142.js b/test/mjsunit/regress/regress-crbug-612142.js
new file mode 100644
index 0000000..de2dc8d
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-612142.js
@@ -0,0 +1,10 @@
+// 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.
+
+var thrower = {[Symbol.toPrimitive]: function(e) { throw e }};
+try {
+  for (var i = 0; i < 10; i++) { }
+  for (var i = 0.5; i < 100000; ++i) { }
+  for (var i = 16 | 0 || 0 || this || 1; i;) { String.fromCharCode(thrower); }
+} catch (e) { }
diff --git a/test/mjsunit/regress/regress-crbug-617524.js b/test/mjsunit/regress/regress-crbug-617524.js
new file mode 100644
index 0000000..b32eeef
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-617524.js
@@ -0,0 +1,18 @@
+// 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-gc --always-opt
+
+function f(a,b,c) {
+  a.a = b;
+  a[1] = c;
+  return a;
+}
+
+f(new Array(5),.5,0);
+var o1 = f(new Array(5),0,.5);
+gc();
+var o2 = f(new Array(5),0,0);
+var o3 = f(new Array(5),0);
+assertEquals(0, o3.a);
diff --git a/test/mjsunit/regress/regress-crbug-620119.js b/test/mjsunit/regress/regress-crbug-620119.js
new file mode 100644
index 0000000..cbe5a78
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-620119.js
@@ -0,0 +1,8 @@
+// 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-lazy
+
+assertEquals(0, ((x, {[(x = function() { y = 0 }, "foo")]: y = eval(1)}) => { x(); return y })(42, {}));
+assertEquals(0, (function (x, {[(x = function() { y = 0 }, "foo")]: y = eval(1)}) { x(); return y })(42, {}));
diff --git a/test/mjsunit/regress/regress-object-assign-deprecated-2.js b/test/mjsunit/regress/regress-object-assign-deprecated-2.js
new file mode 100644
index 0000000..89693de
--- /dev/null
+++ b/test/mjsunit/regress/regress-object-assign-deprecated-2.js
@@ -0,0 +1,8 @@
+// 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.
+
+var x = {a:1, b:2};
+Object.defineProperty(x, "c", {set(v) {}})
+var y = {get c() { return {a:1, b:2.5} }};
+Object.assign(x, y, x);
diff --git a/test/mjsunit/regress/regress-object-assign-deprecated.js b/test/mjsunit/regress/regress-object-assign-deprecated.js
new file mode 100644
index 0000000..d2e60f9
--- /dev/null
+++ b/test/mjsunit/regress/regress-object-assign-deprecated.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.
+
+var x = {a:1, b:2};
+var y = {a:1, b:2.5};
+Object.assign(x, x);
diff --git a/test/mjsunit/regress/regress-observe-map-cache.js b/test/mjsunit/regress/regress-observe-map-cache.js
deleted file mode 100644
index c71759c..0000000
--- a/test/mjsunit/regress/regress-observe-map-cache.js
+++ /dev/null
@@ -1,15 +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.
-
-// Flags: --harmony-object-observe
-// Flags: --allow-natives-syntax --enable-slow-asserts
-
-function f() {
-  var x = new Array(0);
-  x[-1] = -1;
-  Object.observe(x, function() { });
-}
-
-f();
-f();
diff --git a/test/mjsunit/regress/regress-opt-typeof-null.js b/test/mjsunit/regress/regress-opt-typeof-null.js
new file mode 100644
index 0000000..e4721a1
--- /dev/null
+++ b/test/mjsunit/regress/regress-opt-typeof-null.js
@@ -0,0 +1,12 @@
+// 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: --allow-natives-syntax
+
+function f() {
+  return typeof null === "object";
+};
+
+%OptimizeFunctionOnNextCall(f);
+assertTrue(f());
diff --git a/test/mjsunit/regress/regress-recurse-patch-binary-op.js b/test/mjsunit/regress/regress-recurse-patch-binary-op.js
new file mode 100644
index 0000000..842cc79
--- /dev/null
+++ b/test/mjsunit/regress/regress-recurse-patch-binary-op.js
@@ -0,0 +1,10 @@
+// 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.
+
+var i = 0
+function valueOf() {
+  while (true) return i++ < 4 ? 1 + this : 2
+}
+
+1 + ({valueOf})
diff --git a/test/mjsunit/regress/regress-v8-5009.js b/test/mjsunit/regress/regress-v8-5009.js
new file mode 100644
index 0000000..f499548
--- /dev/null
+++ b/test/mjsunit/regress/regress-v8-5009.js
@@ -0,0 +1,61 @@
+// 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 fn1() {
+}
+
+function fn2() {
+}
+
+function fn3() {
+}
+
+function create(id) {
+  // Just some `FunctionTemplate` to hang on
+  var o = new version();
+
+  o.id = id;
+  o[0] = null;
+
+  return o;
+}
+
+function setM1(o) {
+  o.m1 = fn1;
+}
+
+function setM2(o) {
+  o.m2 = fn2;
+}
+
+function setAltM2(o) {
+  // Failing StoreIC happens here
+  o.m2 = fn3;
+}
+
+function setAltM1(o) {
+  o.m1 = null;
+}
+
+function test(o) {
+  o.m2();
+  o.m1();
+}
+
+var p0 = create(0);
+var p1 = create(1);
+var p2 = create(2);
+
+setM1(p0);
+setM1(p1);
+setM1(p2);
+
+setM2(p0);
+setAltM2(p0);
+setAltM1(p0);
+
+setAltM2(p1);
+
+setAltM2(p2);
+test(p2);
diff --git a/test/mjsunit/stack-traces-overflow.js b/test/mjsunit/stack-traces-overflow.js
index e20c609..af81971 100644
--- a/test/mjsunit/stack-traces-overflow.js
+++ b/test/mjsunit/stack-traces-overflow.js
@@ -27,10 +27,22 @@
 
 // Flags: --stack-size=100
 
+function overflow() {
+  var a, b, c, d, e;  // Allocates some locals on the function's stack frame.
+  overflow();
+}
 function rec1(a) { rec1(a+1); }
 function rec2(a) { rec3(a+1); }
 function rec3(a) { rec2(a+1); }
 
+// Test stack trace has correct function location at top of the stack.
+try {
+  overflow();
+} catch (e) {
+  var first_frame = e.stack.split("\n")[1]
+  assertTrue(first_frame.indexOf("stack-traces-overflow.js:30:18") > 0);
+}
+
 // Test stack trace getter and setter.
 try {
   rec1(0);
diff --git a/test/mjsunit/string-wrapper.js b/test/mjsunit/string-wrapper.js
new file mode 100644
index 0000000..d4b6500
--- /dev/null
+++ b/test/mjsunit/string-wrapper.js
@@ -0,0 +1,62 @@
+// 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.
+
+var limit = 10000;
+
+function testStringWrapper(string) {
+  assertEquals('a', string[0]);
+  assertEquals('b', string[1]);
+  assertEquals('c', string[2]);
+}
+
+(function testFastStringWrapperGrow() {
+  var string = new String("abc");
+  for (var i = 0; i < limit; i += 2) {
+    string[i] = {};
+  }
+  testStringWrapper(string);
+
+  for (var i = limit; i > 0; i -= 2) {
+    delete string[i];
+  }
+  testStringWrapper(string);
+})();
+
+(function testSlowStringWrapperGrow() {
+  var string = new String("abc");
+  // Force Slow String Wrapper Elements Kind
+  string[limit] = limit;
+  for (var i = 0; i < limit; i += 2) {
+    string[i] = {};
+  }
+  testStringWrapper(string);
+  assertEquals(limit, string[limit]);
+
+  for (var i = limit; i > 0; i -= 2) {
+    delete string[i];
+  }
+  testStringWrapper(string);
+  assertEquals(undefined, string[limit]);
+})();
+
+
+(function testReconfigureStringWrapperElements() {
+  var s = new String('abc');
+  // Can't reconfigure string contents.
+  assertThrows(() => Object.defineProperty(s, '1', {value: "value"}), TypeError);
+
+  // Configure a property outside the string range
+  var value = 'v1';
+  Object.defineProperty(s, '3', {
+    get: () => {return value},
+    configurable:true
+  });
+  assertEquals('v1', s[3]);
+  value = 'v2';
+  assertEquals('v2', s[3]);
+
+  Object.defineProperty(s, '3', {value: 'v3', configurable: false});
+  assertEquals('v3', s[3]);
+  assertThrows(() => Object.defineProperty(s, '3', {value:2}), TypeError);
+})();
diff --git a/test/mjsunit/tools/tickprocessor-test-func-info.log b/test/mjsunit/tools/tickprocessor-test-func-info.log
index 94aa56d..fcbf3b1 100644
--- a/test/mjsunit/tools/tickprocessor-test-func-info.log
+++ b/test/mjsunit/tools/tickprocessor-test-func-info.log
@@ -1,6 +1,6 @@
-shared-library,"shell",0x08048000,0x081ee000
-shared-library,"/lib32/libm-2.7.so",0xf7db6000,0xf7dd9000
-shared-library,"ffffe000-fffff000",0xffffe000,0xfffff000
+shared-library,"shell",0x08048000,0x081ee000,0
+shared-library,"/lib32/libm-2.7.so",0xf7db6000,0xf7dd9000,0
+shared-library,"ffffe000-fffff000",0xffffe000,0xfffff000,0
 profiler,"begin",1
 code-creation,Stub,0,0x424260,348,"CompareStub_GE"
 code-creation,LazyCompile,0,0x2a8100,18535,"DrawQube 3d-cube.js:188",0xf43abcac,
diff --git a/test/mjsunit/tools/tickprocessor-test.log b/test/mjsunit/tools/tickprocessor-test.log
index cf8b90d..fbc868e 100644
--- a/test/mjsunit/tools/tickprocessor-test.log
+++ b/test/mjsunit/tools/tickprocessor-test.log
@@ -1,6 +1,6 @@
-shared-library,"shell",0x08048000,0x081ee000
-shared-library,"/lib32/libm-2.7.so",0xf7db6000,0xf7dd9000
-shared-library,"ffffe000-fffff000",0xffffe000,0xfffff000
+shared-library,"shell",0x08048000,0x081ee000,0
+shared-library,"/lib32/libm-2.7.so",0xf7db6000,0xf7dd9000,0
+shared-library,"ffffe000-fffff000",0xffffe000,0xfffff000,0
 profiler,"begin",1
 code-creation,Stub,0,0xf540a100,474,"CEntryStub"
 code-creation,Script,0,0xf541cd80,736,"exp.js"
diff --git a/test/mjsunit/tools/tickprocessor.js b/test/mjsunit/tools/tickprocessor.js
index 73af098..804a85d 100644
--- a/test/mjsunit/tools/tickprocessor.js
+++ b/test/mjsunit/tools/tickprocessor.js
@@ -81,7 +81,7 @@
 
   var shell_prov = new UnixCppEntriesProvider();
   var shell_syms = [];
-  shell_prov.parseVmSymbols('shell', 0x08048000, 0x081ee000,
+  shell_prov.parseVmSymbols('shell', 0x08048000, 0x081ee000, 0,
       function (name, start, end) {
         shell_syms.push(Array.prototype.slice.apply(arguments, [0]));
       });
@@ -107,7 +107,7 @@
   };
   var libc_prov = new UnixCppEntriesProvider();
   var libc_syms = [];
-  libc_prov.parseVmSymbols('libc', 0xf7c5c000, 0xf7da5000,
+  libc_prov.parseVmSymbols('libc', 0xf7c5c000, 0xf7da5000, 0,
       function (name, start, end) {
         libc_syms.push(Array.prototype.slice.apply(arguments, [0]));
       });
@@ -145,17 +145,17 @@
 
   var shell_prov = new MacCppEntriesProvider();
   var shell_syms = [];
-  shell_prov.parseVmSymbols('shell', 0x00001b00, 0x00163156,
+  shell_prov.parseVmSymbols('shell', 0x00001c00, 0x00163256, 0x100,
       function (name, start, end) {
         shell_syms.push(Array.prototype.slice.apply(arguments, [0]));
       });
   assertEquals(
-      [['start', 0x00001b00, 0x00001b40],
-       ['dyld_stub_binding_helper', 0x00001b40, 0x0011b710],
-       ['v8::internal::RegExpMacroAssembler::CheckPosition', 0x0011b710, 0x00134250],
-       ['v8::internal::Runtime_StringReplaceRegExpWithString', 0x00134250, 0x00137220],
-       ['v8::internal::Runtime::GetElementOrCharAt', 0x00137220, 0x00137400],
-       ['v8::internal::Runtime_DebugGetPropertyDetails', 0x00137400, 0x00163156]],
+      [['start', 0x00001c00, 0x00001c40],
+       ['dyld_stub_binding_helper', 0x00001c40, 0x0011b810],
+       ['v8::internal::RegExpMacroAssembler::CheckPosition', 0x0011b810, 0x00134350],
+       ['v8::internal::Runtime_StringReplaceRegExpWithString', 0x00134350, 0x00137320],
+       ['v8::internal::Runtime::GetElementOrCharAt', 0x00137320, 0x00137500],
+       ['v8::internal::Runtime_DebugGetPropertyDetails', 0x00137500, 0x00163256]],
       shell_syms);
 
   // stdc++ library
@@ -168,7 +168,7 @@
   };
   var stdc_prov = new MacCppEntriesProvider();
   var stdc_syms = [];
-  stdc_prov.parseVmSymbols('stdc++', 0x95728fb4, 0x95770005,
+  stdc_prov.parseVmSymbols('stdc++', 0x95728fb4, 0x95770005, 0,
       function (name, start, end) {
         stdc_syms.push(Array.prototype.slice.apply(arguments, [0]));
       });
@@ -211,7 +211,7 @@
   };
   var shell_prov = new WindowsCppEntriesProvider();
   var shell_syms = [];
-  shell_prov.parseVmSymbols('shell.exe', 0x00400000, 0x0057c000,
+  shell_prov.parseVmSymbols('shell.exe', 0x00400000, 0x0057c000, 0,
       function (name, start, end) {
         shell_syms.push(Array.prototype.slice.apply(arguments, [0]));
       });
@@ -252,7 +252,7 @@
   read = exeSymbols;
   var exe_exe_syms = [];
   (new WindowsCppEntriesProvider()).parseVmSymbols(
-      'chrome.exe', 0x00400000, 0x00472000,
+      'chrome.exe', 0x00400000, 0x00472000, 0,
       function (name, start, end) {
         exe_exe_syms.push(Array.prototype.slice.apply(arguments, [0]));
       });
@@ -264,7 +264,7 @@
   read = dllSymbols;
   var exe_dll_syms = [];
   (new WindowsCppEntriesProvider()).parseVmSymbols(
-      'chrome.exe', 0x00400000, 0x00472000,
+      'chrome.exe', 0x00400000, 0x00472000, 0,
       function (name, start, end) {
         exe_dll_syms.push(Array.prototype.slice.apply(arguments, [0]));
       });
@@ -275,7 +275,7 @@
   read = dllSymbols;
   var dll_dll_syms = [];
   (new WindowsCppEntriesProvider()).parseVmSymbols(
-      'chrome.dll', 0x01c30000, 0x02b80000,
+      'chrome.dll', 0x01c30000, 0x02b80000, 0,
       function (name, start, end) {
         dll_dll_syms.push(Array.prototype.slice.apply(arguments, [0]));
       });
@@ -287,7 +287,7 @@
   read = exeSymbols;
   var dll_exe_syms = [];
   (new WindowsCppEntriesProvider()).parseVmSymbols(
-      'chrome.dll', 0x01c30000, 0x02b80000,
+      'chrome.dll', 0x01c30000, 0x02b80000, 0,
       function (name, start, end) {
         dll_exe_syms.push(Array.prototype.slice.apply(arguments, [0]));
       });
@@ -304,7 +304,7 @@
 
 
 CppEntriesProviderMock.prototype.parseVmSymbols = function(
-    name, startAddr, endAddr, symbolAdder) {
+    name, startAddr, endAddr, slideAddr, symbolAdder) {
   var symbols = {
     'shell':
         [['v8::internal::JSObject::LookupOwnRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)', 0x080f8800, 0x080f8d90],
diff --git a/test/mjsunit/wasm/adapter-frame.js b/test/mjsunit/wasm/adapter-frame.js
index 0e5d4b8..39164c7 100644
--- a/test/mjsunit/wasm/adapter-frame.js
+++ b/test/mjsunit/wasm/adapter-frame.js
@@ -27,8 +27,10 @@
 
   var builder = new WasmModuleBuilder();
   var sig = new Array();
-  sig.push(type);
+  sig.push(args);
   for (var i = 0; i < args; i++) sig.push(type);
+  sig.push(1);
+  sig.push(type);
   builder.addFunction("select", sig)
     .addBody([kExprGetLocal, which])
     .exportFunc();
diff --git a/test/mjsunit/wasm/asm-wasm-switch.js b/test/mjsunit/wasm/asm-wasm-switch.js
new file mode 100644
index 0000000..bbdb1a2
--- /dev/null
+++ b/test/mjsunit/wasm/asm-wasm-switch.js
@@ -0,0 +1,468 @@
+// 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-wasm
+
+(function TestSwitch0() {
+  function asmModule() {
+    "use asm"
+
+    function caller() {
+      var ret = 0;
+      var x = 7;
+      switch (x) {
+        case 1: {
+          return 0;
+        }
+        case 7: {
+          ret = 5;
+          break;
+        }
+        default: return 0;
+      }
+      return ret|0;
+    }
+
+    return {caller:caller};
+  }
+  var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+  assertEquals(5, wasm.caller());
+})();
+
+(function TestSwitch() {
+  function asmModule() {
+    "use asm"
+
+    function caller() {
+      var ret = 0;
+      var x = 7;
+      switch (x) {
+        case 1: return 0;
+        case 7: {
+          ret = 12;
+          break;
+        }
+        default: return 0;
+      }
+      switch (x) {
+        case 1: return 0;
+        case 8: return 0;
+        default: ret = (ret + 11)|0;
+      }
+      return ret|0;
+    }
+
+    return {caller:caller};
+  }
+  var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+  assertEquals(23, wasm.caller());
+})();
+
+(function TestSwitchFallthrough() {
+  function asmModule() {
+    "use asm"
+
+    function caller() {
+      var x = 17;
+      var ret = 0;
+      switch (x) {
+        case 17:
+        case 14: ret = 39;
+        case 1: ret = (ret + 3)|0;
+        case 4: break;
+        default: ret = (ret + 1)|0;
+      }
+      return ret|0;
+    }
+
+    return {caller:caller};
+  }
+  var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+  assertEquals(42, wasm.caller());
+})();
+
+(function TestNestedSwitch() {
+  function asmModule() {
+    "use asm"
+
+    function caller() {
+      var x = 3;
+      var y = -13;
+      switch (x) {
+        case 1: return 0;
+        case 3: {
+          switch (y) {
+            case 2: return 0;
+            case -13: return 43;
+            default: return 0;
+          }
+        }
+        default: return 0;
+      }
+      return 0;
+    }
+
+    return {caller:caller};
+  }
+  var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+  assertEquals(43, wasm.caller());
+})();
+
+(function TestSwitchWithDefaultOnly() {
+  function asmModule() {
+    "use asm";
+    function main(x) {
+      x = x|0;
+      switch(x|0) {
+        default: return -10;
+      }
+      return 0;
+    }
+    return {
+      main: main,
+    };
+  }
+  var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+  assertEquals(-10, wasm.main(2));
+  assertEquals(-10, wasm.main(54));
+})();
+
+(function TestEmptySwitch() {
+  function asmModule() {
+    "use asm";
+    function main(x) {
+      x = x|0;
+      switch(x|0) {
+      }
+      return 73;
+    }
+    return {
+      main: main,
+    };
+  }
+  var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+  assertEquals(73, wasm.main(7));
+})();
+
+(function TestSwitchWithBrTable() {
+  function asmModule() {
+    "use asm";
+    function main(x) {
+      x = x|0;
+      switch(x|0) {
+        case 14: return 23;
+        case 12: return 25;
+        case 15: return 29;
+        case 19: return 34;
+        case 18: return 17;
+        case 16: return 16;
+        default: return -1;
+      }
+      return 0;
+    }
+    return {
+      main: main,
+    };
+  }
+  var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+  assertEquals(25, wasm.main(12));
+  assertEquals(23, wasm.main(14));
+  assertEquals(29, wasm.main(15));
+  assertEquals(16, wasm.main(16));
+  assertEquals(17, wasm.main(18));
+  assertEquals(34, wasm.main(19));
+  assertEquals(-1, wasm.main(-1));
+})();
+
+(function TestSwitchWithBalancedTree() {
+  function asmModule() {
+    "use asm";
+    function main(x) {
+      x = x|0;
+      switch(x|0) {
+        case 5: return 52;
+        case 1: return 11;
+        case 6: return 63;
+        case 9: return 19;
+        case -4: return -4;
+      }
+      return 0;
+    }
+    return {
+      main: main,
+    };
+  }
+  var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+  assertEquals(-4, wasm.main(-4));
+  assertEquals(11, wasm.main(1));
+  assertEquals(52, wasm.main(5));
+  assertEquals(63, wasm.main(6));
+  assertEquals(19, wasm.main(9));
+  assertEquals(0, wasm.main(11));
+})();
+
+(function TestSwitchHybrid() {
+  function asmModule() {
+    "use asm";
+    function main(x) {
+      x = x|0;
+      switch(x|0) {
+        case 1: return -4;
+        case 2: return 23;
+        case 3: return 32;
+        case 4: return 14;
+        case 7: return 17;
+        case 10: return 10;
+        case 11: return 121;
+        case 12: return 112;
+        case 13: return 31;
+        case 16: return 16;
+        default: return -1;
+      }
+      return 0;
+    }
+    return {
+      main: main,
+    };
+  }
+  var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+  assertEquals(-4, wasm.main(1));
+  assertEquals(23, wasm.main(2));
+  assertEquals(32, wasm.main(3));
+  assertEquals(14, wasm.main(4));
+  assertEquals(17, wasm.main(7));
+  assertEquals(10, wasm.main(10));
+  assertEquals(121, wasm.main(11));
+  assertEquals(112, wasm.main(12));
+  assertEquals(31, wasm.main(13));
+  assertEquals(16, wasm.main(16));
+  assertEquals(-1, wasm.main(20));
+})();
+
+(function TestSwitchFallthroughWithBrTable() {
+  function asmModule() {
+    "use asm";
+    function main(x) {
+      x = x|0;
+      var ret = 0;
+      switch(x|0) {
+        case 1: {
+          ret = 21;
+          break;
+        }
+        case 2: {
+          ret = 12;
+          break;
+        }
+        case 3: {
+          ret = 43;
+        }
+        case 4: {
+          ret = 54;
+          break;
+        }
+        default: {
+          ret = 10;
+          break;
+        }
+      }
+      return ret|0;
+    }
+    return {
+      main: main,
+    };
+  }
+  var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+  assertEquals(12, wasm.main(2));
+  assertEquals(10, wasm.main(10));
+  assertEquals(54, wasm.main(3));
+})();
+
+(function TestSwitchFallthroughHybrid() {
+  function asmModule() {
+    "use asm";
+    function main(x) {
+      x = x|0;
+      var ret = 0;
+      switch(x|0) {
+        case 1: {
+          ret = 1;
+          break;
+        }
+        case 2: {
+          ret = 2;
+          break;
+        }
+        case 3: {
+          ret = 3;
+          break;
+        }
+        case 4: {
+          ret = 4;
+        }
+        case 7: {
+          ret = 7;
+          break;
+        }
+        case 10: {
+          ret = 10;
+        }
+        case 16: {
+          ret = 16;
+          break;
+        }
+        case 17: {
+          ret = 17;
+          break;
+        }
+        case 18: {
+          ret = 18;
+          break;
+        }
+        case 19: {
+          ret = 19;
+        }
+        default: {
+          ret = -1;
+          break;
+        }
+      }
+      return ret|0;
+    }
+    return {
+      main: main,
+    };
+  }
+  var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+  assertEquals(7, wasm.main(4));
+  assertEquals(16, wasm.main(10));
+  assertEquals(-1, wasm.main(19));
+  assertEquals(-1, wasm.main(23));
+})();
+
+(function TestSwitchHybridWithNoDefault() {
+  function asmModule() {
+    "use asm";
+    function main(x) {
+      x = x|0;
+      var ret = 19;
+      switch(x|0) {
+        case 1: {
+          ret = 1;
+          break;
+        }
+        case 2: {
+          ret = 2;
+          break;
+        }
+        case 3: {
+          ret = 3;
+          break;
+        }
+        case 4: {
+          ret = 4;
+          break;
+        }
+        case 7: {
+          ret = 7;
+          break;
+        }
+      }
+      return ret|0;
+    }
+    return {
+      main: main,
+    };
+  }
+  var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+  assertEquals(2, wasm.main(2));
+  assertEquals(7, wasm.main(7));
+  assertEquals(19, wasm.main(-1));
+})();
+
+(function TestLargeSwitch() {
+  function LargeSwitchGenerator(begin, end, gap, handle_case) {
+    var str = "function asmModule() {\
+      \"use asm\";\
+      function main(x) {\
+        x = x|0;\
+        switch(x|0) {";
+    for (var i = begin; i <= end; i = i + gap) {
+      str = str.concat("case ", i.toString(), ": ", handle_case(i));
+    }
+    str = str.concat("default: return -1;\
+        }\
+        return -2;\
+      }\
+      return {main: main}; }");
+
+    var wasm = Wasm.instantiateModuleFromAsm(str);
+    return wasm;
+  }
+
+  var handle_case = function(k) {
+    return "return ".concat(k, ";");
+  }
+  var wasm = LargeSwitchGenerator(0, 513, 1, handle_case);
+  for (var i = 0; i <= 513; i++) {
+    assertEquals(i, wasm.main(i));
+  }
+  assertEquals(-1, wasm.main(-1));
+
+  wasm = LargeSwitchGenerator(0, 1024, 3, handle_case);
+  for (var i = 0; i <= 1024; i = i + 3) {
+    assertEquals(i, wasm.main(i));
+  }
+  assertEquals(-1, wasm.main(-1));
+
+  wasm = LargeSwitchGenerator(-2147483648, -2147483000, 1, handle_case);
+  for (var i = -2147483648; i <= -2147483000; i++) {
+    assertEquals(i, wasm.main(i));
+  }
+  assertEquals(-1, wasm.main(-1));
+  assertEquals(-1, wasm.main(214748647));
+
+  wasm = LargeSwitchGenerator(-2147483648, -2147483000, 3, handle_case);
+  for (var i = -2147483648; i <= -2147483000; i = i + 3) {
+    assertEquals(i, wasm.main(i));
+  }
+  assertEquals(-1, wasm.main(-1));
+  assertEquals(-1, wasm.main(214748647));
+
+  wasm = LargeSwitchGenerator(2147483000, 2147483647, 1, handle_case);
+  for (var i = 2147483000; i <= 2147483647; i++) {
+    assertEquals(i, wasm.main(i));
+  }
+  assertEquals(-1, wasm.main(-1));
+  assertEquals(-1, wasm.main(-214748647));
+
+  wasm = LargeSwitchGenerator(2147483000, 2147483647, 4, handle_case);
+  for (var i = 2147483000; i <= 2147483647; i = i + 4) {
+    assertEquals(i, wasm.main(i));
+  }
+  assertEquals(-1, wasm.main(-1));
+  assertEquals(-1, wasm.main(-214748647));
+
+  handle_case = function(k) {
+    if (k != 7) return "return ".concat(k, ";");
+    else return "break;";
+  }
+  wasm = LargeSwitchGenerator(0, 1499, 7, handle_case);
+  for (var i = 0; i <= 1499; i = i + 7) {
+    if (i == 7) assertEquals(-2, wasm.main(i));
+    else assertEquals(i, wasm.main(i));
+  }
+  assertEquals(-1, wasm.main(-1));
+
+  handle_case = function(k) {
+    if (k != 56) return "break;";
+    else return "return 23;";
+  }
+  wasm = LargeSwitchGenerator(0, 638, 2, handle_case);
+  for (var i = 0; i <= 638; i = i + 2) {
+    if (i == 56) assertEquals(23, wasm.main(i));
+    else assertEquals(-2, wasm.main(i));
+  }
+  assertEquals(-1, wasm.main(-1));
+})();
diff --git a/test/mjsunit/wasm/asm-wasm.js b/test/mjsunit/wasm/asm-wasm.js
index 2efb006..54d7d7a 100644
--- a/test/mjsunit/wasm/asm-wasm.js
+++ b/test/mjsunit/wasm/asm-wasm.js
@@ -23,6 +23,20 @@
 
 assertWasm(11, EmptyTest);
 
+function VoidReturnTest() {
+  "use asm";
+  function caller() {
+    empty();
+    return 19;
+  }
+  function empty() {
+    var x = 0;
+    if (x) return;
+  }
+  return {caller: caller};
+}
+
+assertWasm(19, VoidReturnTest);
 
 function IntTest() {
   "use asm";
@@ -193,6 +207,55 @@
 assertWasm(7, TestReturnInWhileWithoutBraces);
 
 
+function TestBreakInIf() {
+  "use asm";
+
+  function caller() {
+    label: {
+      if(1) break label;
+      return 11;
+    }
+    return 12;
+  }
+
+  return {caller: caller};
+}
+
+assertWasm(12, TestBreakInIf);
+
+function TestBreakInIfInDoWhileFalse() {
+  "use asm";
+
+  function caller() {
+    do {
+      if(1) break;
+      return 11;
+    } while(0);
+    return 12;
+  }
+
+  return {caller: caller};
+}
+
+assertWasm(12, TestBreakInIfInDoWhileFalse);
+
+function TestBreakInElse() {
+  "use asm";
+
+  function caller() {
+    do {
+      if(0) ;
+      else break;
+      return 14;
+    } while(0);
+    return 15;
+  }
+
+  return {caller: caller};
+}
+
+assertWasm(15, TestBreakInElse);
+
 function TestBreakInWhile() {
   "use asm";
 
@@ -209,6 +272,22 @@
 assertWasm(8, TestBreakInWhile);
 
 
+function TestBreakInIfInWhile() {
+  "use asm";
+
+  function caller() {
+    while(1) {
+      if (1) break;
+      else break;
+    }
+    return 8;
+  }
+
+  return {caller: caller};
+}
+
+assertWasm(8, TestBreakInIfInWhile);
+
 function TestBreakInNestedWhile() {
   "use asm";
 
@@ -769,82 +848,6 @@
 assertWasm(41, TestConditional);
 
 
-function TestSwitch() {
-  "use asm"
-
-  function caller() {
-    var ret = 0;
-    var x = 7;
-    switch (x) {
-      case 1: return 0;
-      case 7: {
-        ret = 12;
-        break;
-      }
-      default: return 0;
-    }
-    switch (x) {
-      case 1: return 0;
-      case 8: return 0;
-      default: ret = (ret + 11)|0;
-    }
-    return ret|0;
-  }
-
-  return {caller:caller};
-}
-
-assertWasm(23, TestSwitch);
-
-
-function TestSwitchFallthrough() {
-  "use asm"
-
-  function caller() {
-    var x = 17;
-    var ret = 0;
-    switch (x) {
-      case 17:
-      case 14: ret = 39;
-      case 1: ret = (ret + 3)|0;
-      case 4: break;
-      default: ret = (ret + 1)|0;
-    }
-    return ret|0;
-  }
-
-  return {caller:caller};
-}
-
-assertWasm(42, TestSwitchFallthrough);
-
-
-function TestNestedSwitch() {
-  "use asm"
-
-  function caller() {
-    var x = 3;
-    var y = -13;
-    switch (x) {
-      case 1: return 0;
-      case 3: {
-        switch (y) {
-          case 2: return 0;
-          case -13: return 43;
-          default: return 0;
-        }
-      }
-      default: return 0;
-    }
-    return 0;
-  }
-
-  return {caller:caller};
-}
-
-assertWasm(43, TestNestedSwitch);
-
-
 (function () {
 function TestInitFunctionWithNoGlobals() {
   "use asm";
diff --git a/test/mjsunit/wasm/calls.js b/test/mjsunit/wasm/calls.js
index 11cc92a..94e97e6 100644
--- a/test/mjsunit/wasm/calls.js
+++ b/test/mjsunit/wasm/calls.js
@@ -37,20 +37,42 @@
   assertFalse(exp === null);
   assertFalse(exp === 0);
   assertEquals("function", typeof exp);
-
   return exp;
 }
 
+(function I64SubTest() {
+
+  var builder = new WasmModuleBuilder();
+
+  builder.addMemory(1, 1, true);
+  builder.addFunction("sub", kSig_l_ll)
+    .addBody([           // --
+      kExprGetLocal, 0,  // --
+      kExprGetLocal, 1,  // --
+      kExprI64Sub])      // --
+    .exportFunc()
+
+  var module = builder.instantiate();
+  assertModule(module, kPageSize);
+
+  // Check the properties of the sub function.
+  var sub = assertFunction(module, "sub");
+  assertEquals(-55, sub(33, 88));
+  assertEquals(-55555, sub(33333, 88888));
+  assertEquals(-5555555, sub(3333333, 8888888));
+})();
+
 (function SubTest() {
 
   var builder = new WasmModuleBuilder();
 
   builder.addMemory(1, 1, true);
-  builder.addFunction("sub", [kAstI32, kAstI32, kAstI32])
+  builder.addFunction("sub", kSig_i_ii)
     .addBody([
-      kExprI32Sub,                  // --
       kExprGetLocal, 0,             // --
-      kExprGetLocal, 1])            // --
+      kExprGetLocal, 1,             // --
+      kExprI32Sub,                  // --
+    ])
     .exportFunc()
 
   var module = builder.instantiate();
@@ -70,7 +92,7 @@
 
   var kPages = 2;
   builder.addMemory(kPages, kPages, true);
-  builder.addFunction("nop", [kAstStmt])
+  builder.addFunction("nop", kSig_v_v)
     .addBody([kExprNop])
     .exportFunc();
 
@@ -87,11 +109,12 @@
 
   var kPages = 3;
   builder.addMemory(kPages, kPages, true);
-  builder.addFunction("flt", [kAstI32, kAstF64, kAstF64])
+  builder.addFunction("flt", kSig_i_dd)
     .addBody([
-      kExprF64Lt,           // --
       kExprGetLocal, 0,     // --
-      kExprGetLocal, 1])    // --
+      kExprGetLocal, 1,     // --
+      kExprF64Lt            // --
+    ])                      // --
     .exportFunc();
 
   var module = builder.instantiate();
diff --git a/test/mjsunit/wasm/divrem-trap.js b/test/mjsunit/wasm/divrem-trap.js
index 976e473..6f3ff5d 100644
--- a/test/mjsunit/wasm/divrem-trap.js
+++ b/test/mjsunit/wasm/divrem-trap.js
@@ -33,8 +33,12 @@
 function makeBinop(opcode) {
   var builder = new WasmModuleBuilder();
 
-  builder.addFunction("main", [kAstI32, kAstI32, kAstI32])
-    .addBody([opcode, kExprGetLocal, 0, kExprGetLocal, 1])
+  builder.addFunction("main", kSig_i_ii)
+    .addBody([
+      kExprGetLocal, 0,           // --
+      kExprGetLocal, 1,           // --
+      opcode,                     // --
+    ])
     .exportFunc();
 
   return builder.instantiate().exports.main;
diff --git a/test/mjsunit/wasm/export-table.js b/test/mjsunit/wasm/export-table.js
index e85da9b..a41d85d 100644
--- a/test/mjsunit/wasm/export-table.js
+++ b/test/mjsunit/wasm/export-table.js
@@ -11,11 +11,12 @@
   var kReturnValue = 88;
   var builder = new WasmModuleBuilder();
 
-  builder.addFunction("main", [kAstI32])
+  builder.addFunction("main", kSig_i)
     .addBody([
-      kExprReturn,
       kExprI8Const,
-      kReturnValue])
+      kReturnValue,
+      kExprReturn, kArity1
+    ])
     .exportFunc();
 
   var module = builder.instantiate();
@@ -31,11 +32,12 @@
 
   var builder = new WasmModuleBuilder();
 
-  builder.addFunction("main", [kAstI32])
+  builder.addFunction("main", kSig_i)
     .addBody([
-      kExprReturn,
       kExprI8Const,
-      kReturnValue])
+      kReturnValue,
+      kExprReturn, kArity1
+    ])
     .exportAs("blah")
     .exportAs("foo");
 
@@ -48,3 +50,25 @@
   assertEquals(kReturnValue, module.exports.foo());
   assertEquals(kReturnValue, module.exports.blah());
 })();
+
+
+(function testNumericName() {
+  var kReturnValue = 93;
+
+  var builder = new WasmModuleBuilder();
+
+  builder.addFunction("main", kSig_i)
+    .addBody([
+      kExprI8Const,
+      kReturnValue,
+      kExprReturn, kArity1
+    ])
+    .exportAs("0");
+
+  var module = builder.instantiate();
+
+  assertEquals("object", typeof module.exports);
+  assertEquals("function", typeof module.exports["0"]);
+
+  assertEquals(kReturnValue, module.exports["0"]());
+})();
diff --git a/test/mjsunit/wasm/ffi-error.js b/test/mjsunit/wasm/ffi-error.js
index 649ee27..b6474c6 100644
--- a/test/mjsunit/wasm/ffi-error.js
+++ b/test/mjsunit/wasm/ffi-error.js
@@ -10,13 +10,14 @@
 function testCallFFI(ffi) {
   var builder = new WasmModuleBuilder();
 
-  var sig_index = [kAstI32, kAstF64, kAstF64];
+  var sig_index = kSig_i_dd;
   builder.addImport("fun", sig_index);
   builder.addFunction("main", sig_index)
     .addBody([
-      kExprCallImport, 0,   // --
-      kExprGetLocal, 0,     // --
-      kExprGetLocal, 1])    // --
+      kExprGetLocal, 0,              // --
+      kExprGetLocal, 1,              // --
+      kExprCallFunction, kArity2, 0, // --
+    ])    // --
     .exportFunc();
 
   var module = builder.instantiate(ffi);
diff --git a/test/mjsunit/wasm/ffi.js b/test/mjsunit/wasm/ffi.js
index 61fcf02..87dfe3b 100644
--- a/test/mjsunit/wasm/ffi.js
+++ b/test/mjsunit/wasm/ffi.js
@@ -10,13 +10,14 @@
 function testCallFFI(func, check) {
   var builder = new WasmModuleBuilder();
 
-  var sig_index = builder.addSignature([kAstI32, kAstF64, kAstF64]);
+  var sig_index = builder.addSignature(kSig_i_dd);
   builder.addImport("func", sig_index);
   builder.addFunction("main", sig_index)
     .addBody([
-      kExprCallImport, 0,       // --
-      kExprGetLocal, 0,         // --
-      kExprGetLocal, 1])        // --
+      kExprGetLocal, 0,            // --
+      kExprGetLocal, 1,            // --
+      kExprCallImport, kArity2, 0  // --
+    ])        // --
     .exportFunc();
 
   var main = builder.instantiate({func: func}).exports.main;
@@ -184,14 +185,14 @@
 
   var builder = new WasmModuleBuilder();
 
-  builder.addImport("func", [kAstStmt, type, type]);
-  builder.addFunction("main", [kAstI32, type, type])
+  builder.addImport("func", makeSig_v_xx(type));
+  builder.addFunction("main", makeSig_r_xx(kAstI32, type))
     .addBody([
-      kExprBlock, 2,          // --
-      kExprCallImport, 0,     // --
-      kExprGetLocal, 0,       // --
-      kExprGetLocal, 1,       // --
-      kExprI8Const, 99])      // --
+      kExprGetLocal, 0,            // --
+      kExprGetLocal, 1,            // --
+      kExprCallImport, kArity2, 0, // --
+      kExprI8Const, 99             // --
+    ])                             // --
     .exportFunc()
 
   var main = builder.instantiate(ffi).exports.main;
@@ -240,15 +241,15 @@
 function testCallPrint() {
   var builder = new WasmModuleBuilder();
 
-  builder.addImport("print", [kAstStmt, kAstI32]);
-  builder.addImport("print", [kAstStmt, kAstF64]);
-  builder.addFunction("main", [kAstStmt, kAstF64])
+  builder.addImport("print", makeSig_v_x(kAstI32));
+  builder.addImport("print", makeSig_v_x(kAstF64));
+  builder.addFunction("main", makeSig_v_x(kAstF64))
     .addBody([
-      kExprBlock, 2,            // --
-      kExprCallImport, 0,       // --
-      kExprI8Const, 97,         // --
-      kExprCallImport, 1,       // --
-      kExprGetLocal, 0])        // --
+      kExprI8Const, 97,             // --
+      kExprCallImport, kArity1, 0,  // --
+      kExprGetLocal, 0,             // --
+      kExprCallImport, kArity1, 1   // --
+    ])        // --
     .exportFunc()
 
   var main = builder.instantiate({print: print}).exports.main;
diff --git a/test/mjsunit/wasm/function-prototype.js b/test/mjsunit/wasm/function-prototype.js
index db04b95..25339ad 100644
--- a/test/mjsunit/wasm/function-prototype.js
+++ b/test/mjsunit/wasm/function-prototype.js
@@ -10,7 +10,7 @@
 (function TestFunctionPrototype() {
   var builder = new WasmModuleBuilder();
 
-  builder.addFunction("nine", [kAstI32])
+  builder.addFunction("nine", kSig_i)
     .addBody([kExprI8Const, 9])
     .exportFunc();
 
diff --git a/test/mjsunit/wasm/gc-frame.js b/test/mjsunit/wasm/gc-frame.js
index 8387d26..5fa9b05 100644
--- a/test/mjsunit/wasm/gc-frame.js
+++ b/test/mjsunit/wasm/gc-frame.js
@@ -10,14 +10,13 @@
 function makeFFI(func, t) {
   var builder = new WasmModuleBuilder();
 
-  var sig_index = builder.addSignature([t,t,t,t,t,t,t,t,t,t,t]);
+  var sig_index = builder.addSignature([10,t,t,t,t,t,t,t,t,t,t,1,t]);
   builder.addImport("func", sig_index);
   // Try to create a frame with lots of spilled values and parameters
   // on the stack to try to catch GC bugs in the reference maps for
   // the different parts of the stack.
   builder.addFunction("main", sig_index)
     .addBody([
-      kExprCallImport, 0,       // --
       kExprGetLocal, 0,         // --
       kExprGetLocal, 1,         // --
       kExprGetLocal, 2,         // --
@@ -28,7 +27,7 @@
       kExprGetLocal, 7,         // --
       kExprGetLocal, 8,         // --
       kExprGetLocal, 9,         // --
-      kExprCallImport, 0,       // --
+      kExprCallImport, 10, 0,   // --
       kExprGetLocal, 0,         // --
       kExprGetLocal, 1,         // --
       kExprGetLocal, 2,         // --
@@ -38,7 +37,8 @@
       kExprGetLocal, 6,         // --
       kExprGetLocal, 7,         // --
       kExprGetLocal, 8,         // --
-      kExprGetLocal, 9          // --
+      kExprGetLocal, 9,         // --
+      kExprCallImport, 10, 0    // --
     ])                          // --
     .exportFunc();
 
diff --git a/test/mjsunit/wasm/import-table.js b/test/mjsunit/wasm/import-table.js
index 7579901..c3f8cb9 100644
--- a/test/mjsunit/wasm/import-table.js
+++ b/test/mjsunit/wasm/import-table.js
@@ -10,13 +10,13 @@
 function testCallImport(func, check) {
   var builder = new WasmModuleBuilder();
 
-  var sig_index = builder.addSignature([kAstI32, kAstF64, kAstF64]);
+  var sig_index = builder.addSignature(kSig_i_dd);
   builder.addImport("func", sig_index);
   builder.addFunction("main", sig_index)
     .addBody([
-      kExprCallImport, 0,          // --
       kExprGetLocal, 0,            // --
-      kExprGetLocal, 1])           // --
+      kExprGetLocal, 1,            // --
+      kExprCallImport, 2, 0])      // --
     .exportAs("main");
 
   var main = builder.instantiate({func: func}).exports.main;
@@ -186,14 +186,14 @@
 
   var builder = new WasmModuleBuilder();
 
-  builder.addImport("func", [kAstStmt, type, type]);
-  builder.addFunction("main", [kAstI32, type, type])
+  builder.addImport("func", makeSig_v_xx(type));
+  builder.addFunction("main", makeSig_r_xx(kAstI32, type))
     .addBody([
-      kExprBlock, 2,              // --
-      kExprCallImport, 0,         // --
       kExprGetLocal, 0,           // --
       kExprGetLocal, 1,           // --
-      kExprI8Const, 99])
+      kExprCallImport, 2, 0,      // --
+      kExprI8Const, 99,           // --
+    ])
     .exportFunc("main");
 
   var main = builder.instantiate(ffi).exports.main;
@@ -241,15 +241,15 @@
 
 function testCallPrint() {
   var builder = new WasmModuleBuilder();
-  builder.addImport("print", [kAstStmt, kAstI32]);
-  builder.addImport("print", [kAstStmt, kAstF64]);
-  builder.addFunction("main", [kAstStmt, kAstF64])
+  builder.addImport("print", makeSig_v_x(kAstI32));
+  builder.addImport("print", makeSig_r_x(kAstF64, kAstF64));
+  builder.addFunction("main", makeSig_r_x(kAstF64, kAstF64))
     .addBody([
-      kExprBlock, 2,              // --
-      kExprCallImport, 0,         // --
-      kExprI8Const, 97,           // --
-      kExprCallImport, 1,         // --
-      kExprGetLocal, 0])          // --
+      kExprI8Const, 97,             // --
+      kExprCallImport, kArity1, 0,  // --
+      kExprGetLocal, 0,             // --
+      kExprCallImport, kArity1, 1   // --
+    ])
     .exportFunc();
 
   var main = builder.instantiate({print: print}).exports.main;
@@ -266,13 +266,14 @@
 function testCallImport2(foo, bar, expected) {
   var builder = new WasmModuleBuilder();
 
-  builder.addImport("foo", [kAstI32]);
-  builder.addImport("bar", [kAstI32]);
-  builder.addFunction("main", [kAstI32])
+  builder.addImport("foo", kSig_i);
+  builder.addImport("bar", kSig_i);
+  builder.addFunction("main", kSig_i)
     .addBody([
+      kExprCallImport, kArity0, 0, // --
+      kExprCallImport, kArity0, 1, // --
       kExprI32Add,                 // --
-      kExprCallImport, 0,          // --
-      kExprCallImport, 1])          // --
+    ])                             // --
     .exportFunc();
 
   var main = builder.instantiate({foo: foo, bar: bar}).exports.main;
diff --git a/test/mjsunit/wasm/indirect-calls.js b/test/mjsunit/wasm/indirect-calls.js
index 3258687..80bee41 100644
--- a/test/mjsunit/wasm/indirect-calls.js
+++ b/test/mjsunit/wasm/indirect-calls.js
@@ -10,22 +10,25 @@
 var module = (function () {
   var builder = new WasmModuleBuilder();
 
-  var sig_index = builder.addSignature([kAstI32, kAstI32, kAstI32]);
+  var sig_index = builder.addSignature(kSig_i_ii);
   builder.addImport("add", sig_index);
   builder.addFunction("add", sig_index)
     .addBody([
-      kExprCallImport, 0, kExprGetLocal, 0, kExprGetLocal, 1
+      kExprGetLocal, 0, kExprGetLocal, 1, kExprCallImport, kArity2, 0
     ]);
   builder.addFunction("sub", sig_index)
     .addBody([
-      kExprI32Sub, kExprGetLocal, 0, kExprGetLocal, 1
+      kExprGetLocal, 0,             // --
+      kExprGetLocal, 1,             // --
+      kExprI32Sub,                  // --
     ]);
-  builder.addFunction("main", [kAstI32, kAstI32, kAstI32, kAstI32])
+  builder.addFunction("main", kSig_i_iii)
     .addBody([
-      kExprCallIndirect, sig_index,
       kExprGetLocal, 0,
       kExprGetLocal, 1,
-      kExprGetLocal, 2])
+      kExprGetLocal, 2,
+      kExprCallIndirect, kArity2, sig_index
+    ])
     .exportFunc()
   builder.appendToFunctionTable([0, 1, 2]);
 
diff --git a/test/mjsunit/wasm/instantiate-module-basic.js b/test/mjsunit/wasm/instantiate-module-basic.js
index bc13122..800dcc1 100644
--- a/test/mjsunit/wasm/instantiate-module-basic.js
+++ b/test/mjsunit/wasm/instantiate-module-basic.js
@@ -13,7 +13,7 @@
   var builder = new WasmModuleBuilder();
 
   builder.addMemory(1, 1, true);
-  builder.addFunction("main", [kAstI32])
+  builder.addFunction("main", kSig_i)
     .addBody([kExprI8Const, kReturnValue])
     .exportFunc();
 
diff --git a/test/mjsunit/wasm/instantiate-run-basic.js b/test/mjsunit/wasm/instantiate-run-basic.js
index 2e649a0..fe6fc14 100644
--- a/test/mjsunit/wasm/instantiate-run-basic.js
+++ b/test/mjsunit/wasm/instantiate-run-basic.js
@@ -11,7 +11,7 @@
   var kReturnValue = 107;
   var builder = new WasmModuleBuilder();
 
-  builder.addFunction("main", [kAstI32])
+  builder.addFunction("main", kSig_i_i)
     .addBody([kExprI8Const, kReturnValue])
     .exportFunc();
 
diff --git a/test/mjsunit/wasm/module-memory.js b/test/mjsunit/wasm/module-memory.js
index ef85eb2..a5e5f42 100644
--- a/test/mjsunit/wasm/module-memory.js
+++ b/test/mjsunit/wasm/module-memory.js
@@ -13,19 +13,27 @@
   var builder = new WasmModuleBuilder();
 
   builder.addMemory(1, 1, true);
-  builder.addFunction("main", [kAstI32, kAstI32])
+  builder.addFunction("main", kSig_i_i)
     .addBody([
-      kExprBlock,2,
-        kExprLoop,1,
-          kExprIf,
+    // main body: while(i) { if(mem[i]) return -1; i -= 4; } return 0;
+      kExprLoop,
+        kExprGetLocal,0,
+        kExprIf,
             kExprGetLocal,0,
-            kExprBr, 0,
-              kExprIfElse,
-                kExprI32LoadMem,0,0,kExprGetLocal,0,
-                kExprBr,2, kExprI8Const, 255,
-                kExprSetLocal,0,
-                  kExprI32Sub,kExprGetLocal,0,kExprI8Const,4,
-        kExprI8Const,0])
+          kExprI32LoadMem,0,0,
+          kExprIf,
+            kExprI8Const,255,
+            kExprReturn, kArity1,
+          kExprEnd,
+              kExprGetLocal,0,
+              kExprI8Const,4,
+            kExprI32Sub,
+          kExprSetLocal,0,
+        kExprBr, kArity1, 1,
+        kExprEnd,
+      kExprEnd,
+      kExprI8Const,0
+    ])
     .exportFunc();
 
   return builder.instantiate(null, memory);
@@ -120,14 +128,16 @@
   var builder = new WasmModuleBuilder();
 
   builder.addMemory(1, 1, true);
-  builder.addFunction("geti", [kAstI32, kAstI32, kAstI32])
+  builder.addFunction("geti", kSig_i_ii)
     .addBody([
-      kExprI32StoreMem, 0, 0, kExprGetLocal, 0, kExprI32LoadMem, 0, 0, kExprGetLocal, 1
+      kExprGetLocal, 0,
+      kExprGetLocal, 1,
+      kExprI32LoadMem, 0, 0,
+      kExprI32StoreMem, 0, 0
     ])
     .exportFunc();
 
   var module = builder.instantiate();
-
   var offset;
 
   function read() { return module.exports.geti(0, offset); }
diff --git a/test/mjsunit/wasm/parallel_compilation.js b/test/mjsunit/wasm/parallel_compilation.js
new file mode 100644
index 0000000..23c5658
--- /dev/null
+++ b/test/mjsunit/wasm/parallel_compilation.js
@@ -0,0 +1,100 @@
+// 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-wasm --wasm-num-compilation-tasks=10
+
+load("test/mjsunit/wasm/wasm-constants.js");
+load("test/mjsunit/wasm/wasm-module-builder.js");
+
+function assertModule(module, memsize) {
+  // Check the module exists.
+  assertFalse(module === undefined);
+  assertFalse(module === null);
+  assertFalse(module === 0);
+  assertEquals("object", typeof module);
+
+  // Check the memory is an ArrayBuffer.
+  var mem = module.exports.memory;
+  assertFalse(mem === undefined);
+  assertFalse(mem === null);
+  assertFalse(mem === 0);
+  assertEquals("object", typeof mem);
+  assertTrue(mem instanceof ArrayBuffer);
+  for (var i = 0; i < 4; i++) {
+    module.exports.memory = 0;  // should be ignored
+    assertEquals(mem, module.exports.memory);
+  }
+
+  assertEquals(memsize, module.exports.memory.byteLength);
+}
+
+function assertFunction(module, func) {
+  assertEquals("object", typeof module.exports);
+
+  var exp = module.exports[func];
+  assertFalse(exp === undefined);
+  assertFalse(exp === null);
+  assertFalse(exp === 0);
+  assertEquals("function", typeof exp);
+  return exp;
+}
+
+(function CompileFunctionsTest() {
+
+  var builder = new WasmModuleBuilder();
+
+  builder.addMemory(1, 1, true);
+  for (i = 0; i < 1000; i++) {
+    builder.addFunction("sub" + i, kSig_i_i)
+      .addBody([                // --
+        kExprGetLocal, 0,       // --
+        kExprI32Const, i % 61,  // --
+        kExprI32Sub])           // --
+      .exportFunc()
+  }
+
+  var module = builder.instantiate();
+  assertModule(module, kPageSize);
+
+  // Check the properties of the functions.
+  for (i = 0; i < 1000; i++) {
+    var sub = assertFunction(module, "sub" + i);
+    assertEquals(33 - (i % 61), sub(33));
+  }
+})();
+
+(function CallFunctionsTest() {
+
+  var builder = new WasmModuleBuilder();
+
+  var f = []
+
+  f[0] = builder.addFunction("add0", kSig_i_ii)
+  .addBody([
+            kExprGetLocal, 0,             // --
+            kExprGetLocal, 1,             // --
+            kExprI32Add,                  // --
+          ])
+          .exportFunc()
+
+  builder.addMemory(1, 1, true);
+  for (i = 1; i < 256; i++) {
+    f[i] = builder.addFunction("add" + i, kSig_i_ii)
+      .addBody([                                            // --
+        kExprGetLocal, 0,                                   // --
+        kExprGetLocal, 1,                                   // --
+        kExprCallFunction, kArity2, f[i >>> 1].index])      // --
+      .exportFunc()
+  }
+  var module = builder.instantiate();
+  assertModule(module, kPageSize);
+
+  // Check the properties of the functions.
+  for (i = 0; i < 256; i++) {
+    var add = assertFunction(module, "add" + i);
+    assertEquals(88, add(33, 55));
+    assertEquals(88888, add(33333, 55555));
+    assertEquals(8888888, add(3333333, 5555555));
+  }
+})();
diff --git a/test/mjsunit/wasm/params.js b/test/mjsunit/wasm/params.js
index 7c2b3d1..180ab1c 100644
--- a/test/mjsunit/wasm/params.js
+++ b/test/mjsunit/wasm/params.js
@@ -17,7 +17,7 @@
 
     var builder = new WasmModuleBuilder();
 
-    builder.addFunction("select", [type, type, type])
+    builder.addFunction("select", makeSig_r_xx(type, type))
       .addBody([kExprGetLocal, which])
       .exportFunc()
 
@@ -79,7 +79,7 @@
     print("type = " + t + ", which = " + which);
 
     var builder = new WasmModuleBuilder();
-    builder.addFunction("select", [t,t,t,t,t,t,t,t,t,t,t])
+    builder.addFunction("select", [10,t,t,t,t,t,t,t,t,t,t,1,t])
       .addBody([kExprGetLocal, which])
       .exportFunc();
 
diff --git a/test/mjsunit/wasm/stack.js b/test/mjsunit/wasm/stack.js
index ed05517..a45db94 100644
--- a/test/mjsunit/wasm/stack.js
+++ b/test/mjsunit/wasm/stack.js
@@ -2,39 +2,129 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// clang-format off
 // Flags: --expose-wasm
 
 load("test/mjsunit/wasm/wasm-constants.js");
 load("test/mjsunit/wasm/wasm-module-builder.js");
 
-var expected = "Error\n" +
-    // The line numbers below will change as this test gains / loses lines..
-    "    at STACK (stack.js:24:11)\n" +     // --
-    "    at <WASM> (<anonymous>)\n" +       // TODO(jfb): wasm stack here.
-    "    at testStack (stack.js:38:18)\n" + // --
-    "    at stack.js:40:3";                 // --
-
 // The stack trace contains file path, only keep "stack.js".
 function stripPath(s) {
   return s.replace(/[^ (]*stack\.js/g, "stack.js");
 }
 
+function verifyStack(frames, expected) {
+  assertEquals(expected.length, frames.length, "number of frames mismatch");
+  expected.forEach(function(exp, i) {
+    if (exp[1] != "?") {
+      assertEquals(exp[1], frames[i].getFunctionName(),
+          "["+i+"].getFunctionName()");
+    }
+    assertEquals(exp[2], frames[i].getLineNumber(), "["+i+"].getLineNumber()");
+    if (exp[0])
+      assertEquals(exp[3], frames[i].getPosition(),
+          "["+i+"].getPosition()");
+    assertContains(exp[4], frames[i].getFileName(), "["+i+"].getFileName()");
+    var toString;
+    if (exp[0]) {
+      var funName = exp[1] == "?" ? "" : exp[1];
+      toString = funName + " (<WASM>:" + exp[2] + ":" + exp[3] + ")";
+    } else {
+      toString = exp[4] + ":" + exp[2] + ":";
+    }
+    assertContains(toString, frames[i].toString(), "["+i+"].toString()");
+  });
+}
+
+
 var stack;
 function STACK() {
   var e = new Error();
   stack = e.stack;
 }
 
-(function testStack() {
-  var builder = new WasmModuleBuilder();
+var builder = new WasmModuleBuilder();
 
-  builder.addImport("func", [kAstStmt]);
+builder.addImport("func", kSig_v_v);
 
-  builder.addFunction(undefined, [kAstStmt])
-    .addBody([kExprCallImport, 0])
-    .exportAs("main");
+builder.addFunction("main", kSig_v_v)
+  .addBody([kExprCallImport, kArity0, 0])
+  .exportAs("main");
 
-  var module = builder.instantiate({func: STACK});
+builder.addFunction("exec_unreachable", kSig_v_v)
+  .addBody([kExprUnreachable])
+  .exportAs("exec_unreachable");
+
+// Make this function unnamed, just to test also this case.
+var mem_oob_func = builder.addFunction(undefined, kSig_v_v)
+  // Access the memory at offset -1, to provoke a trap.
+  .addBody([kExprI32Const, 0x7f, kExprI32LoadMem8S, 0, 0])
+  .exportAs("mem_out_of_bounds");
+
+// Call the mem_out_of_bounds function, in order to have two WASM stack frames.
+builder.addFunction("call_mem_out_of_bounds", kSig_v_v)
+  .addBody([kExprCallFunction, kArity0, mem_oob_func.index])
+  .exportAs("call_mem_out_of_bounds");
+
+var module = builder.instantiate({func: STACK});
+
+(function testSimpleStack() {
+  var expected_string = "Error\n" +
+    // The line numbers below will change as this test gains / loses lines..
+    "    at STACK (stack.js:42:11)\n" +           // --
+    "    at main (<WASM>:0:1)\n" +                // --
+    "    at testSimpleStack (stack.js:79:18)\n" + // --
+    "    at stack.js:81:3";                       // --
+
   module.exports.main();
-  assertEquals(expected, stripPath(stack));
+  assertEquals(expected_string, stripPath(stack));
+})();
+
+// For the remaining tests, collect the Callsite objects instead of just a
+// string:
+Error.prepareStackTrace = function(error, frames) {
+  return frames;
+};
+
+(function testStackFrames() {
+  module.exports.main();
+
+  verifyStack(stack, [
+      // isWasm           function   line  pos        file
+      [   false,           "STACK",    42,   0, "stack.js"],
+      [    true,            "main",     0,   1,       null],
+      [   false, "testStackFrames",    90,   0, "stack.js"],
+      [   false,              null,    99,   0, "stack.js"]
+  ]);
+})();
+
+(function testWasmUnreachable() {
+  try {
+    module.exports.exec_unreachable();
+    fail("expected wasm exception");
+  } catch (e) {
+    assertContains("unreachable", e.message);
+    verifyStack(e.stack, [
+        // isWasm               function   line  pos        file
+        [    true,    "exec_unreachable",    1,    1,       null],
+        [   false, "testWasmUnreachable",  103,    0, "stack.js"],
+        [   false,                  null,  114,    0, "stack.js"]
+    ]);
+  }
+})();
+
+(function testWasmMemOutOfBounds() {
+  try {
+    module.exports.call_mem_out_of_bounds();
+    fail("expected wasm exception");
+  } catch (e) {
+    assertContains("out of bounds", e.message);
+    verifyStack(e.stack, [
+        // isWasm                  function   line  pos        file
+        [    true,                      "?",     2,   3,       null],
+        [    true, "call_mem_out_of_bounds",     3,   1,       null],
+        [   false, "testWasmMemOutOfBounds",   118,   0, "stack.js"],
+        [   false,                     null,   130,   0, "stack.js"]
+    ]);
+  }
 })();
diff --git a/test/mjsunit/wasm/stackwalk.js b/test/mjsunit/wasm/stackwalk.js
index 8b8fb7e..5e5a1ef 100644
--- a/test/mjsunit/wasm/stackwalk.js
+++ b/test/mjsunit/wasm/stackwalk.js
@@ -10,13 +10,14 @@
 function makeFFI(func) {
   var builder = new WasmModuleBuilder();
 
-  var sig_index = builder.addSignature([kAstI32, kAstF64, kAstF64]);
+  var sig_index = builder.addSignature(kSig_i_dd);
   builder.addImport("func", sig_index);
   builder.addFunction("main", sig_index)
     .addBody([
-      kExprCallImport, 0,       // --
-      kExprGetLocal, 0,         // --
-      kExprGetLocal, 1])        // --
+      kExprGetLocal, 0,            // --
+      kExprGetLocal, 1,            // --
+      kExprCallImport, kArity2, 0, // --
+    ])
     .exportFunc()
 
   return builder.instantiate({func: func}).exports.main;
diff --git a/test/mjsunit/wasm/start-function.js b/test/mjsunit/wasm/start-function.js
index bd4ccf2..3c5707a 100644
--- a/test/mjsunit/wasm/start-function.js
+++ b/test/mjsunit/wasm/start-function.js
@@ -37,19 +37,19 @@
   return module;
 }
 
-assertVerifies([kAstStmt], [kExprNop]);
-assertVerifies([kAstI32], [kExprI8Const, 0]);
+assertVerifies(kSig_v_v, [kExprNop]);
+assertVerifies(kSig_i, [kExprI8Const, 0]);
 
 // Arguments aren't allow to start functions.
-assertFails([kAstI32, kAstI32], [kExprGetLocal, 0]);
-assertFails([kAstI32, kAstI32, kAstF32], [kExprGetLocal, 0]);
-assertFails([kAstI32, kAstI32, kAstF32, kAstF64], [kExprGetLocal, 0]);
+assertFails(kSig_i_i, [kExprGetLocal, 0]);
+assertFails(kSig_i_ii, [kExprGetLocal, 0]);
+assertFails(kSig_i_dd, [kExprGetLocal, 0]);
 
 (function testInvalidIndex() {
   print("testInvalidIndex");
   var builder = new WasmModuleBuilder();
 
-  var func = builder.addFunction("", [kAstStmt])
+  var func = builder.addFunction("", kSig_v_v)
     .addBody([kExprNop]);
 
   builder.addStart(func.index + 1);
@@ -62,7 +62,7 @@
   print("testTwoStartFuncs");
   var builder = new WasmModuleBuilder();
 
-  var func = builder.addFunction("", [kAstStmt])
+  var func = builder.addFunction("", kSig_v_v)
     .addBody([kExprNop]);
 
   builder.addExplicitSection([kDeclStartFunction, 0]);
@@ -78,8 +78,8 @@
 
   builder.addMemory(12, 12, true);
 
-  var func = builder.addFunction("", [kAstStmt])
-    .addBody([kExprI32StoreMem, 0, 0, kExprI8Const, 0, kExprI8Const, 77]);
+  var func = builder.addFunction("", kSig_v_v)
+    .addBody([kExprI8Const, 0, kExprI8Const, 77, kExprI32StoreMem, 0, 0]);
 
   builder.addStart(func.index);
 
@@ -98,11 +98,11 @@
   }};
 
   var builder = new WasmModuleBuilder();
-  var sig_index = builder.addSignature([kAstStmt]);
+  var sig_index = builder.addSignature(kSig_v_v);
 
   builder.addImport("foo", sig_index);
   var func = builder.addFunction("", sig_index)
-    .addBody([kExprCallImport, 0]);
+    .addBody([kExprCallImport, kArity0, 0]);
 
   builder.addStart(func.index);
 
diff --git a/test/mjsunit/wasm/test-wasm-module-builder.js b/test/mjsunit/wasm/test-wasm-module-builder.js
index 50797d0..969b550 100644
--- a/test/mjsunit/wasm/test-wasm-module-builder.js
+++ b/test/mjsunit/wasm/test-wasm-module-builder.js
@@ -12,7 +12,7 @@
 (function BasicTest() {
     var module = new WasmModuleBuilder();
     module.addMemory(1, 2, false);
-    module.addFunction("foo", [kAstI32])
+    module.addFunction("foo", kSig_i)
         .addBody([kExprI8Const, 11])
         .exportAs("blarg");
 
@@ -23,9 +23,9 @@
 
 (function ImportTest() {
     var module = new WasmModuleBuilder();
-    var index = module.addImport("print", [kAstStmt, kAstI32]);
-    module.addFunction("foo", [kAstStmt])
-        .addBody([kExprCallImport, index, kExprI8Const, 13])
+    var index = module.addImport("print", makeSig_v_x(kAstI32));
+    module.addFunction("foo", kSig_v_v)
+        .addBody([kExprI8Const, 13, kExprCallImport, kArity1, index])
         .exportAs("main");
 
     var buffer = module.toBuffer(debug);
@@ -36,9 +36,9 @@
 
 (function LocalsTest() {
     var module = new WasmModuleBuilder();
-    module.addFunction(undefined, [kAstI32, kAstI32])
+    module.addFunction(undefined, kSig_i_i)
         .addLocals({i32_count: 1})
-        .addBody([kExprSetLocal, 1, kExprGetLocal, 0])
+        .addBody([kExprGetLocal, 0, kExprSetLocal, 1])
         .exportAs("main");
 
     var buffer = module.toBuffer(debug);
@@ -58,9 +58,9 @@
 
     for (p of types) {
       var module = new WasmModuleBuilder();
-      module.addFunction(undefined, [p.type, p.type])
+      module.addFunction(undefined, makeSig_r_x(p.type, p.type))
         .addLocals(p.locals)
-        .addBody([kExprSetLocal, 1, kExprGetLocal, 0])
+        .addBody([kExprGetLocal, 0, kExprSetLocal, 1])
         .exportAs("main");
 
       var buffer = module.toBuffer(debug);
@@ -72,10 +72,10 @@
 
 (function CallTest() {
     var module = new WasmModuleBuilder();
-    module.addFunction("add", [kAstI32, kAstI32, kAstI32])
-        .addBody([kExprI32Add, kExprGetLocal, 0, kExprGetLocal, 1]);
-    module.addFunction("main", [kAstI32, kAstI32, kAstI32])
-        .addBody([kExprCallFunction, 0, kExprGetLocal, 0, kExprGetLocal, 1])
+    module.addFunction("add", kSig_i_ii)
+        .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32Add]);
+    module.addFunction("main", kSig_i_ii)
+        .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprCallFunction, kArity2, 0])
         .exportAs("main");
 
     var instance = module.instantiate();
@@ -85,11 +85,11 @@
 
 (function IndirectCallTest() {
     var module = new WasmModuleBuilder();
-    module.addFunction("add", [kAstI32, kAstI32, kAstI32])
-        .addBody([kExprI32Add, kExprGetLocal, 0, kExprGetLocal, 1]);
-    module.addFunction("main", [kAstI32, kAstI32, kAstI32, kAstI32])
-        .addBody([kExprCallIndirect, 0, kExprGetLocal,
-                  0, kExprGetLocal, 1, kExprGetLocal, 2])
+    module.addFunction("add", kSig_i_ii)
+        .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32Add]);
+    module.addFunction("main", kSig_i_iii)
+        .addBody([kExprGetLocal,
+                  0, kExprGetLocal, 1, kExprGetLocal, 2, kExprCallIndirect, kArity2, 0])
         .exportAs("main");
     module.appendToFunctionTable([0]);
 
@@ -102,8 +102,8 @@
 (function DataSegmentTest() {
     var module = new WasmModuleBuilder();
     module.addMemory(1, 1, false);
-    module.addFunction("load", [kAstI32, kAstI32])
-        .addBody([kExprI32LoadMem, 0, 0, kExprGetLocal, 0])
+    module.addFunction("load", kSig_i_i)
+        .addBody([kExprGetLocal, 0, kExprI32LoadMem, 0, 0])
         .exportAs("load");
     module.addDataSegment(0, [9, 9, 9, 9], true);
 
@@ -116,7 +116,7 @@
 (function BasicTestWithUint8Array() {
     var module = new WasmModuleBuilder();
     module.addMemory(1, 2, false);
-    module.addFunction("foo", [kAstI32])
+    module.addFunction("foo", kSig_i)
         .addBody([kExprI8Const, 17])
         .exportAs("blarg");
 
@@ -141,9 +141,9 @@
 
 (function ImportTestTwoLevel() {
     var module = new WasmModuleBuilder();
-    var index = module.addImportWithModule("mod", "print", [kAstStmt, kAstI32]);
-    module.addFunction("foo", [kAstStmt])
-        .addBody([kExprCallImport, index, kExprI8Const, 19])
+    var index = module.addImportWithModule("mod", "print", makeSig_v_x(kAstI32));
+    module.addFunction("foo", kSig_v_v)
+        .addBody([kExprI8Const, 19, kExprCallImport, kArity1, index])
         .exportAs("main");
 
     var buffer = module.toBuffer(debug);
diff --git a/test/mjsunit/wasm/trap-location.js b/test/mjsunit/wasm/trap-location.js
new file mode 100644
index 0000000..5e3661d
--- /dev/null
+++ b/test/mjsunit/wasm/trap-location.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-wasm
+
+load("test/mjsunit/wasm/wasm-constants.js");
+load("test/mjsunit/wasm/wasm-module-builder.js");
+
+// Collect the Callsite objects instead of just a string:
+Error.prepareStackTrace = function(error, frames) {
+  return frames;
+};
+
+var builder = new WasmModuleBuilder();
+
+var sig_index = builder.addSignature(kSig_i_v)
+
+// Build a function to resemble this code:
+//   if (idx < 2) {
+//     return load(-2 / idx);
+//   } else if (idx == 2) {
+//     unreachable;
+//   } else {
+//     return call_indirect(idx);
+//   }
+// There are four different traps which are triggered by different input values:
+// (0) division by zero; (1) mem oob; (2) unreachable; (3) invalid call target
+// Each of them also has a different location where it traps.
+builder.addFunction("main", kSig_i_i)
+  .addBody([
+      // offset 1
+      kExprBlock,
+            kExprGetLocal, 0,
+            kExprI32Const, 2,
+          kExprI32LtU,
+        kExprIf,
+        // offset 8
+              kExprI32Const, 0x7e /* -2 */,
+              kExprGetLocal, 0,
+            kExprI32DivU,
+          // offset 13
+          kExprI32LoadMem, 0, 0,
+          kExprBr, 1, 1,
+        kExprEnd,
+        // offset 20
+            kExprGetLocal, 0,
+            kExprI32Const, 2,
+          kExprI32Eq,
+        kExprIf,
+          kExprUnreachable,
+        kExprEnd,
+        // offset 28
+          kExprGetLocal, 0,
+        kExprCallIndirect, kArity0, sig_index,
+      kExprEnd,
+  ])
+  .exportAs("main");
+
+var module = builder.instantiate();
+
+function testWasmTrap(value, reason, position) {
+  try {
+    module.exports.main(value);
+    fail("expected wasm exception");
+  } catch (e) {
+    assertEquals(kTrapMsgs[reason], e.message, "trap reason");
+    assertEquals(3, e.stack.length, "number of frames");
+    assertEquals(0, e.stack[0].getLineNumber(), "wasmFunctionIndex");
+    assertEquals(position, e.stack[0].getPosition(), "position");
+  }
+}
+
+// The actual tests:
+testWasmTrap(0, kTrapDivByZero,      12);
+testWasmTrap(1, kTrapMemOutOfBounds, 13);
+testWasmTrap(2, kTrapUnreachable,    26);
+testWasmTrap(3, kTrapFuncInvalid,    30);
diff --git a/test/mjsunit/wasm/unicode-validation.js b/test/mjsunit/wasm/unicode-validation.js
new file mode 100644
index 0000000..b2e4603
--- /dev/null
+++ b/test/mjsunit/wasm/unicode-validation.js
@@ -0,0 +1,121 @@
+// 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-wasm
+
+load("test/mjsunit/wasm/wasm-constants.js");
+load("test/mjsunit/wasm/wasm-module-builder.js");
+
+function toByteArray(s) {
+  var arr = [];
+  for (var i = 0; i < s.length; ++i) {
+    arr.push(s.charCodeAt(i) & 0xff);
+  }
+  return arr;
+}
+
+function toString(arr) {
+  if (typeof arr === "string") return arr;
+  var s = "";
+  for (var b of arr) s += String.fromCharCode(b);
+  return s;
+}
+
+function toUTF8(arr) {
+  if (typeof arr === "string" || arr === undefined) return arr;
+  return decodeURIComponent(escape(toString(arr)));
+}
+
+function isValidUtf8(arr) {
+  if (typeof arr === "string" || arr === undefined) return true;
+  try {
+    var s = toUTF8(arr);
+    for (var i = 0; i < s.length; ++i)
+      if ((s.charCodeAt(i) & 0xfffe) == 0xfffe)
+        return false;
+    return true;
+  } catch (e) {
+    if (e instanceof URIError) return false;
+    throw e;
+  }
+}
+
+function checkImportsAndExports(imported_module_name, imported_function_name,
+    internal_function_name, exported_function_name, shouldThrow) {
+  var builder = new WasmModuleBuilder();
+
+  builder.addImportWithModule(imported_module_name, imported_function_name,
+      kSig_v_v);
+
+  builder.addFunction(internal_function_name, kSig_v_v)
+    .addBody([kExprCallImport, kArity0, 0])
+    .exportAs(exported_function_name);
+
+  // sanity check: does javascript agree with out shouldThrow annotation?
+  assertEquals(shouldThrow,
+      !isValidUtf8(imported_module_name) ||
+          !isValidUtf8(imported_function_name) ||
+          !isValidUtf8(exported_function_name),
+      "JavaScript does not agree with our shouldThrow expectation");
+
+  if (!shouldThrow) {
+    imported_module_name = toUTF8(imported_module_name);
+    imported_function_name = toUTF8(imported_function_name);
+  }
+
+  var ffi = new Object();
+  if (imported_function_name === undefined) {
+    ffi[imported_module_name] = function() { };
+  } else {
+    ffi[imported_module_name] = new Object();
+    ffi[imported_module_name][imported_function_name] = function() { };
+  }
+
+  var hasThrown = true;
+  try {
+    builder.instantiate(ffi);
+    hasThrown = false;
+  } catch (err) {
+    if (!shouldThrow) print(err);
+    assertTrue(shouldThrow, "Should not throw error on valid names");
+    assertContains("UTF-8", err.toString());
+  }
+  assertEquals(shouldThrow, hasThrown,
+      "Should throw validation error on invalid names");
+}
+
+function checkImportedModuleName(name, shouldThrow) {
+  checkImportsAndExports(name, "imp", "func", undefined, shouldThrow);
+}
+
+function checkImportedFunctionName(name, shouldThrow) {
+  checkImportsAndExports("module", name, "func", "func", shouldThrow);
+}
+
+function checkExportedFunctionName(name, shouldThrow) {
+  checkImportsAndExports("module", "func", "func", name, shouldThrow);
+}
+
+function checkInternalFunctionName(name) {
+  checkImportsAndExports("module", "func", name, "func", false);
+}
+
+function checkAll(name, shouldThrow) {
+  checkImportedModuleName(name, shouldThrow);
+  checkImportedFunctionName(name, shouldThrow);
+  checkExportedFunctionName(name, shouldThrow);
+  checkInternalFunctionName(name);
+}
+
+checkAll("ascii", false);
+checkAll("some math: (½)² = ¼", false);
+checkAll("中国历史系列条目\n北", false);
+checkAll(toByteArray("\xef\xb7\x8f"), false);
+checkAll(toByteArray("a\xc2\x81\xe1\x80\xbf\xf1\x80\xa0\xbf"), false);
+checkAll(toByteArray("\xff"), true);
+checkAll(toByteArray("\xed\xa0\x8f"), true);        // surrogate code points
+checkAll(toByteArray("\xe0\x82\x80"), true);        // overlong sequence
+checkAll(toByteArray("\xf4\x90\x80\x80"), true);    // beyond limit: U+110000
+checkAll(toByteArray("\xef\xbf\xbe"), true);        // non-character; U+FFFE
+checkAll(toByteArray("with\x00null"), false);
diff --git a/test/mjsunit/wasm/unreachable.js b/test/mjsunit/wasm/unreachable.js
index 3e2dffb..d77b53e 100644
--- a/test/mjsunit/wasm/unreachable.js
+++ b/test/mjsunit/wasm/unreachable.js
@@ -9,7 +9,7 @@
 
 var main = (function () {
   var builder = new WasmModuleBuilder();
-  builder.addFunction("main", [kAstStmt])
+  builder.addFunction("main", kSig_v_v)
     .addBody([kExprUnreachable])
     .exportAs("main");
 
@@ -23,4 +23,4 @@
     print("correctly caught: " + e);
     exception = e;
 }
-assertEquals("unreachable", exception);
+assertEquals("unreachable", exception.message);
diff --git a/test/mjsunit/wasm/verify-function-simple.js b/test/mjsunit/wasm/verify-function-simple.js
index aa5c676..31c23a6 100644
--- a/test/mjsunit/wasm/verify-function-simple.js
+++ b/test/mjsunit/wasm/verify-function-simple.js
@@ -8,9 +8,9 @@
 
 try {
   var data = bytes(
-      0,       kAstStmt,  // signature
-      kDeclNoLocals,      // --
-      kExprNop            // body
+      kWasmFunctionTypeForm, 0, kAstStmt,  // signature
+      kDeclNoLocals,                       // --
+      kExprNop                             // body
   );
 
   Wasm.verifyFunction(data);
@@ -23,9 +23,9 @@
 var threw = false;
 try {
   var data = bytes(
-      0,       kAstI32,   // signature
-      kDeclNoLocals,      // --
-      kExprBlock, 2, kExprNop, kExprNop  // body
+      kWasmFunctionTypeForm, 0, 1, kAstI32,     // signature
+      kDeclNoLocals,                            // --
+      kExprBlock, kExprNop, kExprNop, kExprEnd  // body
   );
 
   Wasm.verifyFunction(data);
diff --git a/test/mjsunit/wasm/wasm-constants.js b/test/mjsunit/wasm/wasm-constants.js
index cc620bb..389383e 100644
--- a/test/mjsunit/wasm/wasm-constants.js
+++ b/test/mjsunit/wasm/wasm-constants.js
@@ -21,7 +21,7 @@
 var kWasmH2 = 0x73;
 var kWasmH3 = 0x6d;
 
-var kWasmV0 = 10;
+var kWasmV0 = 11;
 var kWasmV1 = 0;
 var kWasmV2 = 0;
 var kWasmV3 = 0;
@@ -65,10 +65,16 @@
 var kDeclFunctionBodies = 0x0b;
 var kDeclNames = 0x0c;
 
+var kArity0 = 0;
+var kArity1 = 1;
+var kArity2 = 2;
+var kArity3 = 3;
+var kWasmFunctionTypeForm = 0x40;
+
 var section_names = [
-  "memory", "signatures", "functions", "globals", "data_segments",
-  "function_table", "end", "start_function", "import_table", "export_table",
-  "function_signatures", "function_bodies", "names"];
+  "memory", "type", "old_function", "global", "data",
+  "table", "end", "start", "import", "export",
+  "function", "code", "name"];
 
 // Function declaration flags
 var kDeclFunctionName   = 0x01;
@@ -83,31 +89,60 @@
 var kAstF32 = 3;
 var kAstF64 = 4;
 
+// Useful signatures
+var kSig_i = [0, 1, kAstI32];
+var kSig_d = [0, 1, kAstF64];
+var kSig_i_i = [1, kAstI32, 1, kAstI32];
+var kSig_i_ii = [2, kAstI32, kAstI32, 1, kAstI32];
+var kSig_i_iii = [3, kAstI32, kAstI32, kAstI32, 1, kAstI32];
+var kSig_d_dd = [2, kAstF64, kAstF64, 1, kAstF64];
+var kSig_l_ll = [2, kAstI64, kAstI64, 1, kAstI64];
+var kSig_i_dd = [2, kAstF64, kAstF64, 1, kAstI32];
+var kSig_v_v = [0, 0];
+var kSig_i_v = [0, 1, kAstI32];
+
+function makeSig_v_xx(x) {
+  return [2, x, x, 0];
+}
+
+function makeSig_v_x(x) {
+  return [1, x, 0];
+}
+
+function makeSig_r_xx(r, x) {
+  return [2, x, x, 1, r];
+}
+
+function makeSig_r_x(r, x) {
+  return [1, x, 1, r];
+}
+
 // Opcodes
 var kExprNop = 0x00;
 var kExprBlock = 0x01;
 var kExprLoop = 0x02;
 var kExprIf = 0x03;
-var kExprIfElse = 0x04;
+var kExprElse = 0x04;
 var kExprSelect = 0x05;
 var kExprBr = 0x06;
 var kExprBrIf = 0x07;
-var kExprTableSwitch = 0x08;
-var kExprReturn = 0x14;
-var kExprUnreachable = 0x15;
+var kExprBrTable = 0x08;
+var kExprReturn = 0x09;
+var kExprUnreachable = 0x0a;
+var kExprEnd = 0x0f;
 
-var kExprI8Const = 0x09;
-var kExprI32Const = 0x0a;
-var kExprI64Const = 0x0b;
-var kExprF64Const = 0x0c;
-var kExprF32Const = 0x0d;
-var kExprGetLocal = 0x0e;
-var kExprSetLocal = 0x0f;
-var kExprLoadGlobal = 0x10;
-var kExprStoreGlobal = 0x11;
-var kExprCallFunction = 0x12;
-var kExprCallIndirect = 0x13;
-var kExprCallImport = 0x1F;
+var kExprI32Const = 0x10;
+var kExprI64Const = 0x11;
+var kExprF64Const = 0x12;
+var kExprF32Const = 0x13;
+var kExprGetLocal = 0x14;
+var kExprSetLocal = 0x15;
+var kExprCallFunction = 0x16;
+var kExprCallIndirect = 0x17;
+var kExprCallImport = 0x18;
+var kExprI8Const = 0xcb;
+var kExprLoadGlobal = 0xcc;
+var kExprStoreGlobal = 0xcd;
 
 var kExprI32LoadMem8S = 0x20;
 var kExprI32LoadMem8U = 0x21;
@@ -290,8 +325,8 @@
       }
       threwException = false;
     } catch (e) {
-      assertEquals("string", typeof e);
-      assertEquals(kTrapMsgs[trap], e);
+      assertEquals("object", typeof e);
+      assertEquals(kTrapMsgs[trap], e.message);
       // Success.
       return;
     }
diff --git a/test/mjsunit/wasm/wasm-module-builder.js b/test/mjsunit/wasm/wasm-module-builder.js
index e1d9963..bfc4460 100644
--- a/test/mjsunit/wasm/wasm-module-builder.js
+++ b/test/mjsunit/wasm/wasm-module-builder.js
@@ -53,7 +53,7 @@
   return this;
 }
 
-// Add a signature; format is [rettype, param0, param1, ...]
+// Add a signature; format is [param_count, param0, param1, ..., retcount, ret0]
 WasmModuleBuilder.prototype.addSignature = function(sig) {
     // TODO: canonicalize signatures?
     this.signatures.push(sig);
@@ -75,9 +75,7 @@
 }
 
 WasmModuleBuilder.prototype.addImport = function(name, sig) {
-  var sig_index = (typeof sig) == "number" ? sig : this.addSignature(sig);
-  this.imports.push({module: name, name: undefined, sig_index: sig_index});
-  return this.imports.length - 1;
+  this.addImportWithModule(name, undefined, sig);
 }
 
 WasmModuleBuilder.prototype.addDataSegment = function(addr, data, init) {
@@ -107,9 +105,19 @@
 }
 
 function emit_string(bytes, string) {
-    emit_varint(bytes, string.length);
-    for (var i = 0; i < string.length; i++) {
-      emit_u8(bytes, string.charCodeAt(i));
+    // When testing illegal names, we pass a byte array directly.
+    if (string instanceof Array) {
+      emit_varint(bytes, string.length);
+      emit_bytes(bytes, string);
+      return;
+    }
+
+    // This is the hacky way to convert a JavaScript scring to a UTF8 encoded
+    // string only containing single-byte characters.
+    var string_utf8 = unescape(encodeURIComponent(string));
+    emit_varint(bytes, string_utf8.length);
+    for (var i = 0; i < string_utf8.length; i++) {
+      emit_u8(bytes, string_utf8.charCodeAt(i));
     }
 }
 
@@ -132,12 +140,14 @@
 }
 
 function emit_section(bytes, section_code, content_generator) {
-    // Start the section in a temporary buffer: its full length isn't know yet.
+    // Emit section name.
+    emit_string(bytes, section_names[section_code]);
+    // Emit the section to a temporary buffer: its full length isn't know yet.
     var tmp_bytes = [];
-    emit_string(tmp_bytes, section_names[section_code]);
     content_generator(tmp_bytes);
-    // Now that we know the section length, emit it and copy the section.
+    // Emit section length.
     emit_varint(bytes, tmp_bytes.length);
+    // Copy the temporary buffer.
     Array.prototype.push.apply(bytes, tmp_bytes);
 }
 
@@ -149,24 +159,13 @@
 
     var wasm = this;
 
-    // Add memory section
-    if (wasm.memory != undefined) {
-        if (debug) print("emitting memory @ " + bytes.length);
-        emit_section(bytes, kDeclMemory, function(bytes) {
-            emit_varint(bytes, wasm.memory.min);
-            emit_varint(bytes, wasm.memory.max);
-            emit_u8(bytes, wasm.memory.exp ? 1 : 0);
-        });
-    }
-
     // Add signatures section
     if (wasm.signatures.length > 0) {
         if (debug) print("emitting signatures @ " + bytes.length);
         emit_section(bytes, kDeclSignatures, function(bytes) {
             emit_varint(bytes, wasm.signatures.length);
             for (sig of wasm.signatures) {
-                var params = sig.length - 1;
-                emit_varint(bytes, params);
+                emit_u8(bytes, kWasmFunctionTypeForm);
                 for (var j = 0; j < sig.length; j++) {
                     emit_u8(bytes, sig[j]);
                 }
@@ -187,7 +186,7 @@
         });
     }
 
-    // Add functions section
+    // Add functions declarations
     var names = false;
     var exports = 0;
     if (wasm.functions.length > 0) {
@@ -206,6 +205,54 @@
             }
         });
 
+    }
+
+    // Add function table.
+    if (wasm.function_table.length > 0) {
+        if (debug) print("emitting function table @ " + bytes.length);
+        emit_section(bytes, kDeclFunctionTable, function(bytes) {
+            emit_varint(bytes, wasm.function_table.length);
+            for (index of wasm.function_table) {
+                emit_varint(bytes, index);
+            }
+        });
+    }
+
+    // Add memory section
+    if (wasm.memory != undefined) {
+        if (debug) print("emitting memory @ " + bytes.length);
+        emit_section(bytes, kDeclMemory, function(bytes) {
+            emit_varint(bytes, wasm.memory.min);
+            emit_varint(bytes, wasm.memory.max);
+            emit_u8(bytes, wasm.memory.exp ? 1 : 0);
+        });
+    }
+
+
+    // Add export table.
+    if (exports > 0) {
+        if (debug) print("emitting exports @ " + bytes.length);
+        emit_section(bytes, kDeclExportTable, function(bytes) {
+            emit_varint(bytes, exports);
+            for (func of wasm.functions) {
+                for (exp of func.exports) {
+                    emit_varint(bytes, func.index);
+                    emit_string(bytes, exp);
+                }
+            }
+        });
+    }
+
+    // Add start function section.
+    if (wasm.start_index != undefined) {
+        if (debug) print("emitting start function @ " + bytes.length);
+        emit_section(bytes, kDeclStartFunction, function(bytes) {
+            emit_varint(bytes, wasm.start_index);
+        });
+    }
+
+    // Add function bodies.
+    if (wasm.functions.length > 0) {
         // emit function bodies
         if (debug) print("emitting function bodies @ " + bytes.length);
         emit_section(bytes, kDeclFunctionBodies, function(bytes) {
@@ -244,50 +291,7 @@
         });
     }
 
-    // emit function names
-    if (has_names) {
-        if (debug) print("emitting names @ " + bytes.length);
-        emit_section(bytes, kDeclNames, function(bytes) {
-            emit_varint(bytes, wasm.functions.length);
-            for (func of wasm.functions) {
-                var name = func.name == undefined ? "" : func.name;
-               emit_string(bytes, name);
-               emit_u8(bytes, 0);  // local names count == 0
-            }
-        });
-    }
-
-    // Add start function section.
-    if (wasm.start_index != undefined) {
-        if (debug) print("emitting start function @ " + bytes.length);
-        emit_section(bytes, kDeclStartFunction, function(bytes) {
-            emit_varint(bytes, wasm.start_index);
-        });
-    }
-
-    if (wasm.function_table.length > 0) {
-        if (debug) print("emitting function table @ " + bytes.length);
-        emit_section(bytes, kDeclFunctionTable, function(bytes) {
-            emit_varint(bytes, wasm.function_table.length);
-            for (index of wasm.function_table) {
-                emit_varint(bytes, index);
-            }
-        });
-    }
-
-    if (exports > 0) {
-        if (debug) print("emitting exports @ " + bytes.length);
-        emit_section(bytes, kDeclExportTable, function(bytes) {
-            emit_varint(bytes, exports);
-            for (func of wasm.functions) {
-                for (exp of func.exports) {
-                    emit_varint(bytes, func.index);
-                    emit_string(bytes, exp);
-                }
-            }
-        });
-    }
-
+    // Add data segments.
     if (wasm.data_segments.length > 0) {
         if (debug) print("emitting data segments @ " + bytes.length);
         emit_section(bytes, kDeclDataSegments, function(bytes) {
@@ -300,12 +304,25 @@
         });
     }
 
-    // Emit any explicitly added sections
+    // Add any explicitly added sections
     for (exp of wasm.explicit) {
         if (debug) print("emitting explicit @ " + bytes.length);
         emit_bytes(bytes, exp);
     }
 
+    // Add function names.
+    if (has_names) {
+        if (debug) print("emitting names @ " + bytes.length);
+        emit_section(bytes, kDeclNames, function(bytes) {
+            emit_varint(bytes, wasm.functions.length);
+            for (func of wasm.functions) {
+                var name = func.name == undefined ? "" : func.name;
+                emit_string(bytes, name);
+                emit_u8(bytes, 0);  // local names count == 0
+            }
+        });
+    }
+
     // End the module.
     if (debug) print("emitting end @ " + bytes.length);
     emit_section(bytes, kDeclEnd, function(bytes) {});
diff --git a/test/mjsunit/wasm/wasm-object-api.js b/test/mjsunit/wasm/wasm-object-api.js
index 2f25c66..96088b8 100644
--- a/test/mjsunit/wasm/wasm-object-api.js
+++ b/test/mjsunit/wasm/wasm-object-api.js
@@ -10,3 +10,4 @@
 assertEquals("function", typeof Wasm.verifyFunction);
 assertEquals("function", typeof Wasm.instantiateModule);
 assertEquals("function", typeof Wasm.instantiateModuleFromAsm);
+assertFalse(undefined == Wasm.experimentalVersion);