Merge V8 at 3.7.12.28

Bug: 5688872

Change-Id: Iddb40cae44d51a2b449f2858951e0472771f5981
diff --git a/test/mjsunit/apply.js b/test/mjsunit/apply.js
index c166110..413ee93 100644
--- a/test/mjsunit/apply.js
+++ b/test/mjsunit/apply.js
@@ -190,3 +190,10 @@
     "moreseper-prime");
 
 delete(Array.prototype["1"]);
+
+// Check correct handling of non-array argument lists.
+assertSame(this, f0.apply(this, {}), "non-array-1");
+assertSame(this, f0.apply(this, { length:1 }), "non-array-2");
+assertEquals(void 0, f1.apply(this, { length:1 }), "non-array-3");
+assertEquals(void 0, f1.apply(this, { 0:"foo" }), "non-array-4");
+assertEquals("foo", f1.apply(this, { length:1, 0:"foo" }), "non-array-5");
diff --git a/test/mjsunit/array-literal-transitions.js b/test/mjsunit/array-literal-transitions.js
new file mode 100644
index 0000000..321340c
--- /dev/null
+++ b/test/mjsunit/array-literal-transitions.js
@@ -0,0 +1,125 @@
+// 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: --allow-natives-syntax --smi-only-arrays --expose-gc
+// Test element kind of objects.
+// Since --smi-only-arrays affects builtins, its default setting at compile
+// time sticks if built with snapshot.  If --smi-only-arrays is deactivated
+// by default, only a no-snapshot build actually has smi-only arrays enabled
+// in this test case.  Depending on whether smi-only arrays are actually
+// enabled, this test takes the appropriate code path to check smi-only arrays.
+
+support_smi_only_arrays = %HasFastSmiOnlyElements(new Array());
+
+// IC and Crankshaft support for smi-only elements in dynamic array literals.
+function get(foo) { return foo; }  // Used to generate dynamic values.
+
+function array_literal_test() {
+  var a0 = [1, 2, 3];
+  assertTrue(%HasFastSmiOnlyElements(a0));
+  var a1 = [get(1), get(2), get(3)];
+  assertTrue(%HasFastSmiOnlyElements(a1));
+
+  var b0 = [1, 2, get("three")];
+  assertTrue(%HasFastElements(b0));
+  var b1 = [get(1), get(2), get("three")];
+  assertTrue(%HasFastElements(b1));
+
+  var c0 = [1, 2, get(3.5)];
+  assertTrue(%HasFastDoubleElements(c0));
+  assertEquals(3.5, c0[2]);
+  assertEquals(2, c0[1]);
+  assertEquals(1, c0[0]);
+
+  var c1 = [1, 2, 3.5];
+  assertTrue(%HasFastDoubleElements(c1));
+  assertEquals(3.5, c1[2]);
+  assertEquals(2, c1[1]);
+  assertEquals(1, c1[0]);
+
+  var c2 = [get(1), get(2), get(3.5)];
+  assertTrue(%HasFastDoubleElements(c2));
+  assertEquals(3.5, c2[2]);
+  assertEquals(2, c2[1]);
+  assertEquals(1, c2[0]);
+
+  var object = new Object();
+  var d0 = [1, 2, object];
+  assertTrue(%HasFastElements(d0));
+  assertEquals(object, d0[2]);
+  assertEquals(2, d0[1]);
+  assertEquals(1, d0[0]);
+
+  var e0 = [1, 2, 3.5];
+  assertTrue(%HasFastDoubleElements(e0));
+  assertEquals(3.5, e0[2]);
+  assertEquals(2, e0[1]);
+  assertEquals(1, e0[0]);
+
+  var f0 = [1, 2, [1, 2]];
+  assertTrue(%HasFastElements(f0));
+  assertEquals([1,2], f0[2]);
+  assertEquals(2, f0[1]);
+  assertEquals(1, f0[0]);
+}
+
+if (support_smi_only_arrays) {
+  for (var i = 0; i < 3; i++) {
+    array_literal_test();
+  }
+  %OptimizeFunctionOnNextCall(array_literal_test);
+  array_literal_test();
+
+  function test_large_literal() {
+
+    function d() {
+      gc();
+      return 2.5;
+    }
+
+    function o() {
+      gc();
+      return new Object();
+    }
+
+    large =
+        [ 0, 1, 2, 3, 4, 5, d(), d(), d(), d(), d(), d(), o(), o(), o(), o() ];
+    assertFalse(%HasDictionaryElements(large));
+    assertFalse(%HasFastSmiOnlyElements(large));
+    assertFalse(%HasFastDoubleElements(large));
+    assertTrue(%HasFastElements(large));
+    assertEquals(large,
+                 [0, 1, 2, 3, 4, 5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5,
+                  new Object(), new Object(), new Object(), new Object()]);
+  }
+
+  for (var i = 0; i < 3; i++) {
+    test_large_literal();
+  }
+  %OptimizeFunctionOnNextCall(test_large_literal);
+  test_large_literal();
+}
diff --git a/test/mjsunit/array-tostring.js b/test/mjsunit/array-tostring.js
new file mode 100644
index 0000000..6708657
--- /dev/null
+++ b/test/mjsunit/array-tostring.js
@@ -0,0 +1,159 @@
+// 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.
+
+// Array's toString should call the object's own join method, if one exists and
+// is callable. Otherwise, just use the original Object.toString function.
+
+var success = "[test success]";
+var expectedThis;
+function testJoin() {
+  assertEquals(0, arguments.length);
+  assertSame(expectedThis, this);
+  return success;
+}
+
+
+// On an Array object.
+
+// Default case.
+var a1 = [1, 2, 3];
+assertEquals(a1.join(), a1.toString());
+
+// Non-standard "join" function is called correctly.
+var a2 = [1, 2, 3];
+a2.join = testJoin;
+expectedThis = a2;
+assertEquals(success, a2.toString());
+
+// Non-callable join function is ignored and Object.prototype.toString is
+// used instead.
+var a3 = [1, 2, 3];
+a3.join = "not callable";
+assertEquals("[object Array]", a3.toString());
+
+// Non-existing join function is treated same as non-callable.
+var a4 = [1, 2, 3];
+a4.__proto__ = { toString: Array.prototype.toString };
+// No join on Array.
+assertEquals("[object Array]", a4.toString());
+
+
+// On a non-Array object.
+
+// Default looks-like-an-array case.
+var o1 = {length: 3, 0: 1, 1: 2, 2: 3,
+          toString: Array.prototype.toString,
+          join: Array.prototype.join};
+assertEquals(o1.join(), o1.toString());
+
+
+// Non-standard join is called correctly.
+// Check that we don't read, e.g., length before calling join.
+var o2 = {toString : Array.prototype.toString,
+          join: testJoin,
+          get length() { assertUnreachable(); },
+          get 0() { assertUnreachable(); }};
+expectedThis = o2;
+assertEquals(success, o2.toString());
+
+// Non-standard join is called even if it looks like an array.
+var o3 = {length: 3, 0: 1, 1: 2, 2: 3,
+          toString: Array.prototype.toString,
+          join: testJoin};
+expectedThis = o3;
+assertEquals(success, o3.toString());
+
+// Non-callable join works same as for Array.
+var o4 = {length: 3, 0: 1, 1: 2, 2: 3,
+          toString: Array.prototype.toString,
+          join: "not callable"};
+assertEquals("[object Object]", o4.toString());
+
+
+// Non-existing join works same as for Array.
+var o5 = {length: 3, 0: 1, 1: 2, 2: 3,
+          toString: Array.prototype.toString
+          /* no join */};
+assertEquals("[object Object]", o5.toString());
+
+
+// Test that ToObject is called before getting "join", so the instance
+// that "join" is read from is the same one passed as receiver later.
+var called_before = false;
+expectedThis = null;
+Object.defineProperty(Number.prototype, "join", {get: function() {
+            assertFalse(called_before);
+            called_before = true;
+            expectedThis = this;
+            return testJoin;
+        }});
+Number.prototype.arrayToString = Array.prototype.toString;
+assertEquals(success, (42).arrayToString());
+
+// ----------------------------------------------------------
+// Testing Array.prototype.toLocaleString
+
+// Ensure that it never uses Array.prototype.toString for anything.
+Array.prototype.toString = function() { assertUnreachable(); };
+
+// Default case.
+var la1 = [1, [2, 3], 4];
+assertEquals("1,2,3,4", la1.toLocaleString());
+
+// Used on a string (which looks like an array of characters).
+String.prototype.toLocaleString = Array.prototype.toLocaleString;
+assertEquals("1,2,3,4", "1234".toLocaleString());
+
+// If toLocaleString of element is not callable, throw a TypeError.
+var la2 = [1, {toLocaleString: "not callable"}, 3];
+assertThrows(function() { la2.toLocaleString(); }, TypeError);
+
+// If toLocaleString of element is callable, call it.
+var la3 = [1, {toLocaleString: function() { return "XX";}}, 3];
+assertEquals("1,XX,3", la3.toLocaleString());
+
+// Omitted elements, as well as undefined and null, become empty string.
+var la4 = [1, null, 3, undefined, 5,, 7];
+assertEquals("1,,3,,5,,7", la4.toLocaleString());
+
+
+// ToObject is called first and the same object is being used for the
+// rest of the operations.
+Object.defineProperty(Number.prototype, "length", {
+    get: function() {
+      exptectedThis = this;
+      return 3;
+    }});
+for (var i = 0; i < 3; i++) {
+  Object.defineProperty(Number.prototype, i, {
+      get: function() {
+        assertEquals(expectedThis, this);
+        return +this;
+      }});
+}
+Number.prototype.arrayToLocaleString = Array.prototype.toLocaleString;
+assertEquals("42,42,42", (42).arrayToLocaleString());
\ No newline at end of file
diff --git a/test/mjsunit/assert-opt-and-deopt.js b/test/mjsunit/assert-opt-and-deopt.js
index c9adb5b..51cb99a 100644
--- a/test/mjsunit/assert-opt-and-deopt.js
+++ b/test/mjsunit/assert-opt-and-deopt.js
@@ -150,11 +150,6 @@
 
 f(1);
 
-tracker.AssertOptCount(f, 0);
-tracker.AssertIsOptimized(f, false);
-tracker.AssertDeoptHappened(f, false);
-tracker.AssertDeoptCount(f, 0);
-
 %OptimizeFunctionOnNextCall(f);
 f(1);
 
@@ -172,6 +167,7 @@
 
 // Let's trigger optimization for another type.
 for (var i = 0; i < 5; i++) f("a");
+
 %OptimizeFunctionOnNextCall(f);
 f("b");
 
diff --git a/test/mjsunit/bugs/bug-618.js b/test/mjsunit/bugs/bug-618.js
index ae84326..0513f87 100644
--- a/test/mjsunit/bugs/bug-618.js
+++ b/test/mjsunit/bugs/bug-618.js
@@ -42,4 +42,4 @@
 
 assertEquals(23, new C().x);
 C.prototype.__defineSetter__('x', function(value) { this.y = 23; });
-assertEquals(void 0, new C().x));
+assertEquals(void 0, new C().x);
diff --git a/test/mjsunit/bugs/harmony/debug-blockscopes.js b/test/mjsunit/bugs/harmony/debug-blockscopes.js
index a407c53..fda32eb 100644
--- a/test/mjsunit/bugs/harmony/debug-blockscopes.js
+++ b/test/mjsunit/bugs/harmony/debug-blockscopes.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: --expose-debug-as debug --harmony-block-scoping
+// Flags: --expose-debug-as debug --harmony-scoping
 // The functions used for testing backtraces. They are at the top to make the
 // testing of source line/column easier.
 
diff --git a/test/mjsunit/compiler/compare.js b/test/mjsunit/compiler/compare.js
index 3f96087..460b0ab 100644
--- a/test/mjsunit/compiler/compare.js
+++ b/test/mjsunit/compiler/compare.js
@@ -83,9 +83,9 @@
 }
 
 TestNonPrimitive("xy", MaxLT);
-TestNonPrimitive("yx", MaxLE);
+TestNonPrimitive("xy", MaxLE);
 TestNonPrimitive("xy", MaxGE);
-TestNonPrimitive("yx", MaxGT);
+TestNonPrimitive("xy", MaxGT);
 
 // Test compare in case of aliased registers.
 function CmpX(x) { if (x == x) return 42; }
diff --git a/test/mjsunit/cyclic-error-to-string.js b/test/mjsunit/compiler/inline-context-slots.js
similarity index 78%
copy from test/mjsunit/cyclic-error-to-string.js
copy to test/mjsunit/compiler/inline-context-slots.js
index 2502b53..d0e907b 100644
--- a/test/mjsunit/cyclic-error-to-string.js
+++ b/test/mjsunit/compiler/inline-context-slots.js
@@ -25,22 +25,25 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Test printing of cyclic errors which return the empty string for
-// compatibility with Safari and Firefox.
+// Test inlining of functions with context slots.
 
-var e = new Error();
-assertEquals('Error', e + '');
+// Flags: --allow-natives-syntax
 
-e = new Error();
-e.name = e;
-e.message = e;
-e.stack = e;
-e.arguments = e;
-assertEquals(': ', e + '');
 
-e = new Error();
-e.name = [ e ];
-e.message = [ e ];
-e.stack = [ e ];
-e.arguments = [ e ];
-assertEquals(': ', e + '');
+// Caller/callee without a local context.
+
+(function() {
+  var X = 5;
+  var Y = 10;
+  function F() {}
+  F.prototype.max = function() {
+    return X > Y ? X : Y;
+  }
+  F.prototype.run = function() {
+    return this.max();
+  }
+  var f = new F();
+  for (var i=0; i<5; i++) f.run();
+  %OptimizeFunctionOnNextCall(f.run);
+  assertEquals(10, f.run());
+})();
diff --git a/test/mjsunit/regress/regress-221.js b/test/mjsunit/compiler/lazy-const-lookup.js
similarity index 85%
copy from test/mjsunit/regress/regress-221.js
copy to test/mjsunit/compiler/lazy-const-lookup.js
index d3f2e35..b4f15a1 100644
--- a/test/mjsunit/regress/regress-221.js
+++ b/test/mjsunit/compiler/lazy-const-lookup.js
@@ -1,4 +1,4 @@
-// Copyright 2009 the V8 project authors. All rights reserved.
+// 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:
@@ -25,10 +25,17 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Test that direct eval calls handle the case where eval has been
-// deleted correctly.
+// Flags: --allow-natives-syntax
 
-// See http://code.google.com/p/v8/issues/detail?id=221
+function outer() {
+  const x = 1;
+  function inner() {
+    return x;
+  }
+  inner();
+  %OptimizeFunctionOnNextCall(inner);
+  inner();
+}
 
-assertThrows('eval(delete eval)');
+outer();
 
diff --git a/test/mjsunit/regress/regress-221.js b/test/mjsunit/compiler/regress-96989.js
similarity index 81%
copy from test/mjsunit/regress/regress-221.js
copy to test/mjsunit/compiler/regress-96989.js
index d3f2e35..aedeb24 100644
--- a/test/mjsunit/regress/regress-221.js
+++ b/test/mjsunit/compiler/regress-96989.js
@@ -1,4 +1,4 @@
-// Copyright 2009 the V8 project authors. All rights reserved.
+// 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:
@@ -25,10 +25,19 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Test that direct eval calls handle the case where eval has been
-// deleted correctly.
 
-// See http://code.google.com/p/v8/issues/detail?id=221
+// Flags: --allow-natives-syntax
 
-assertThrows('eval(delete eval)');
+// Test correct handling of uninitialized const.
 
+function test() {
+  for (var i = 41; i < 42; i++) {
+    var c = t ^ i;
+  }
+  const t;
+  return c;
+}
+
+for (var i=0; i<10; i++) test();
+%OptimizeFunctionOnNextCall(test);
+assertEquals(41, test());
diff --git a/test/mjsunit/cyclic-error-to-string.js b/test/mjsunit/compiler/regress-deopt-call-as-function.js
similarity index 66%
copy from test/mjsunit/cyclic-error-to-string.js
copy to test/mjsunit/compiler/regress-deopt-call-as-function.js
index 2502b53..c408096 100644
--- a/test/mjsunit/cyclic-error-to-string.js
+++ b/test/mjsunit/compiler/regress-deopt-call-as-function.js
@@ -25,22 +25,38 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Test printing of cyclic errors which return the empty string for
-// compatibility with Safari and Firefox.
+// Test deoptimization after inlined call.
 
-var e = new Error();
-assertEquals('Error', e + '');
+function bar(a, b) {try { return a; } finally { } }
 
-e = new Error();
-e.name = e;
-e.message = e;
-e.stack = e;
-e.arguments = e;
-assertEquals(': ', e + '');
+function test_context() {
+  function foo(x) { return 42; }
+  var s, t;
+  for (var i = 0x7fff0000; i < 0x80000000; i++) {
+    bar(t = foo(i) ? bar(42 + i - i) : bar(0), s = i + t);
+  }
+  return s;
+}
+assertEquals(0x7fffffff + 42, test_context());
 
-e = new Error();
-e.name = [ e ];
-e.message = [ e ];
-e.stack = [ e ];
-e.arguments = [ e ];
-assertEquals(': ', e + '');
+
+function value_context() {
+  function foo(x) { return 42; }
+  var s, t;
+  for (var i = 0x7fff0000; i < 0x80000000; i++) {
+    bar(t = foo(i), s = i + t);
+  }
+  return s;
+}
+assertEquals(0x7fffffff + 42, value_context());
+
+
+function effect_context() {
+  function foo(x) { return 42; }
+  var s, t;
+  for (var i = 0x7fff0000; i < 0x80000000; i++) {
+    bar(foo(i), s = i + 42);
+  }
+  return s;
+}
+assertEquals(0x7fffffff + 42, effect_context());
diff --git a/test/mjsunit/cyclic-error-to-string.js b/test/mjsunit/compiler/regress-inline-callfunctionstub.js
similarity index 80%
rename from test/mjsunit/cyclic-error-to-string.js
rename to test/mjsunit/compiler/regress-inline-callfunctionstub.js
index 2502b53..a39d26d 100644
--- a/test/mjsunit/cyclic-error-to-string.js
+++ b/test/mjsunit/compiler/regress-inline-callfunctionstub.js
@@ -25,22 +25,22 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Test printing of cyclic errors which return the empty string for
-// compatibility with Safari and Firefox.
+// Flags: --allow-natives-syntax
 
-var e = new Error();
-assertEquals('Error', e + '');
+// Test inlined of calls-as-function two levels deep.
+function f() { return 42; }
 
-e = new Error();
-e.name = e;
-e.message = e;
-e.stack = e;
-e.arguments = e;
-assertEquals(': ', e + '');
+var o = {g : function () { return f(); } }
+function main(func) {
+  var v=0;
+  for (var i=0; i<1; i++) {
+    if (func()) v = 42;
+  }
+}
 
-e = new Error();
-e.name = [ e ];
-e.message = [ e ];
-e.stack = [ e ];
-e.arguments = [ e ];
-assertEquals(': ', e + '');
+main(o.g);
+main(o.g);
+main(o.g);
+%OptimizeFunctionOnNextCall(main);
+main(o.g);
+
diff --git a/test/mjsunit/cyclic-error-to-string.js b/test/mjsunit/compiler/strict-recompile.js
similarity index 77%
copy from test/mjsunit/cyclic-error-to-string.js
copy to test/mjsunit/compiler/strict-recompile.js
index 2502b53..96e8bca 100644
--- a/test/mjsunit/cyclic-error-to-string.js
+++ b/test/mjsunit/compiler/strict-recompile.js
@@ -25,22 +25,27 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Test printing of cyclic errors which return the empty string for
-// compatibility with Safari and Firefox.
+// Flags: --allow-natives-syntax
 
-var e = new Error();
-assertEquals('Error', e + '');
+function foo() {
+  try {
+    var o = {};
+    Object.defineProperty(o, 'x', {value: 12, writable: false});
+    o.x = 13;
+  } catch(e) {
+    return true;
+  }
+  return false;
+}
 
-e = new Error();
-e.name = e;
-e.message = e;
-e.stack = e;
-e.arguments = e;
-assertEquals(': ', e + '');
+assertFalse(foo());
 
-e = new Error();
-e.name = [ e ];
-e.message = [ e ];
-e.stack = [ e ];
-e.arguments = [ e ];
-assertEquals(': ', e + '');
+function do_eval(str) {
+  "use strict";
+  return eval(str);
+}
+
+var eval_foo = do_eval('(' + foo + ')');
+for (var i = 0; i < 5; i++) assertTrue(eval_foo());
+%OptimizeFunctionOnNextCall(eval_foo);
+assertTrue(eval_foo());
diff --git a/test/mjsunit/const-redecl.js b/test/mjsunit/const-redecl.js
index 9459708..c0b97e6 100644
--- a/test/mjsunit/const-redecl.js
+++ b/test/mjsunit/const-redecl.js
@@ -98,7 +98,8 @@
   var msg = s;
   if (opt_e) { e = opt_e; msg += "; " + opt_e; }
   assertEquals(expected, TestLocal(s,e), "local:'" + msg + "'");
-  assertEquals(expected, TestGlobal(s,e), "global:'" + msg + "'");
+  // Redeclarations of global consts do not throw, they are silently ignored.
+  assertEquals(42, TestGlobal(s, 42), "global:'" + msg + "'");
   assertEquals(expected, TestContext(s,e), "context:'" + msg + "'");
 }
 
@@ -218,3 +219,62 @@
 // Test that const inside with behaves correctly.
 TestAll(87, "with ({x:42}) { const x = 87; }", "x");
 TestAll(undefined, "with ({x:42}) { const x; }", "x");
+
+
+// Additional tests for how various combinations of re-declarations affect
+// the values of the var/const in question.
+try {
+  eval("var undefined;");
+} catch (ex) {
+  assertUnreachable("undefined (1) has thrown");
+}
+
+var original_undef = undefined;
+var undefined = 1;  // Should be silently ignored.
+assertEquals(original_undef, undefined, "undefined got overwritten");
+undefined = original_undef;
+
+var a; const a; const a = 1;
+assertEquals(1, a, "a has wrong value");
+a = 2;
+assertEquals(2, a, "a should be writable");
+
+var b = 1; const b = 2;
+assertEquals(2, b, "b has wrong value");
+
+var c = 1; const c = 2; const c = 3;
+assertEquals(3, c, "c has wrong value");
+
+const d = 1; const d = 2;
+assertEquals(1, d, "d has wrong value");
+
+const e = 1; var e = 2;
+assertEquals(1, e, "e has wrong value");
+
+const f = 1; const f;
+assertEquals(1, f, "f has wrong value");
+
+var g; const g = 1;
+assertEquals(1, g, "g has wrong value");
+g = 2;
+assertEquals(2, g, "g should be writable");
+
+const h; var h = 1;
+assertEquals(undefined,h,  "h has wrong value");
+
+eval("Object.defineProperty(this, 'i', { writable: true });"
+   + "const i = 7;"
+   + "assertEquals(7, i, \"i has wrong value\");");
+
+var global = this;
+assertThrows(function() {
+  Object.defineProperty(global, 'j', { writable: true })
+}, TypeError);
+const j = 2;  // This is what makes the function above throw, because the
+// const declaration gets hoisted and makes the property non-configurable.
+assertEquals(2, j, "j has wrong value");
+
+var k = 1; const k;
+// You could argue about the expected result here. For now, the winning
+// argument is that "const k;" is equivalent to "const k = undefined;".
+assertEquals(undefined, k, "k has wrong value");
diff --git a/test/mjsunit/date.js b/test/mjsunit/date.js
index a7f6cfa..fa43cbb 100644
--- a/test/mjsunit/date.js
+++ b/test/mjsunit/date.js
@@ -157,7 +157,7 @@
 // Test that -0 is treated correctly in MakeDay.
 var d = new Date();
 assertDoesNotThrow("d.setDate(-0)");
-assertDoesNotThrow("new Date(-0, -0, -0, -0, -0, -0. -0)");
+assertDoesNotThrow("new Date(-0, -0, -0, -0, -0, -0, -0)");
 assertDoesNotThrow("new Date(0x40000000, 0x40000000, 0x40000000," +
                    "0x40000000, 0x40000000, 0x40000000, 0x40000000)")
 assertDoesNotThrow("new Date(-0x40000001, -0x40000001, -0x40000001," +
@@ -178,7 +178,7 @@
 assertTrue(isNaN(Date.UTC(-271821, 3, 19)));
 
 
-// Test creation of large date values.
+// Test creation with large date values.
 d = new Date(1969, 12, 1, 99999999999);
 assertTrue(isNaN(d.getTime()));
 d = new Date(1969, 12, 1, -99999999999);
@@ -188,6 +188,12 @@
 d = new Date(1969, 12, 1, -Infinity);
 assertTrue(isNaN(d.getTime()));
 
+
+// Test creation with obscure date values.
+assertEquals(8640000000000000, Date.UTC(1970, 0, 1 + 100000001, -24));
+assertEquals(-8640000000000000, Date.UTC(1970, 0, 1 - 100000001, 24));
+
+
 // Parsing ES5 ISO-8601 dates.
 // When TZ is omitted, it defaults to 'Z' meaning UTC.
 
diff --git a/test/mjsunit/debug-break-inline.js b/test/mjsunit/debug-break-inline.js
new file mode 100644
index 0000000..4418fa8
--- /dev/null
+++ b/test/mjsunit/debug-break-inline.js
@@ -0,0 +1,100 @@
+// 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: --expose-debug-as debug --allow-natives-syntax
+
+// This test tests that deoptimization due to debug breaks works for
+// inlined functions where the full-code is generated before the
+// debugger is attached.
+//
+//See http://code.google.com/p/chromium/issues/detail?id=105375
+
+// Get the Debug object exposed from the debug context global object.
+Debug = debug.Debug;
+
+var count = 0;
+var break_count = 0;
+
+// Debug event listener which sets a breakpoint first time it is hit
+// and otherwise counts break points hit and checks that the expected
+// state is reached.
+function listener(event, exec_state, event_data, data) {
+  if (event == Debug.DebugEvent.Break) {
+    break_count++;
+    if (break_count == 1) {
+      Debug.setBreakPoint(g, 3);
+
+      for (var i = 0; i < exec_state.frameCount(); i++) {
+        var frame = exec_state.frame(i);
+        // When function f is optimized (1 means YES, see runtime.cc) we
+        // expect an optimized frame for f and g.
+        if (%GetOptimizationStatus(f) == 1) {
+          if (i == 1) {
+            assertTrue(frame.isOptimizedFrame());
+            assertTrue(frame.isInlinedFrame());
+            assertEquals(4 - i, frame.inlinedFrameIndex());
+          } else if (i == 2) {
+            assertTrue(frame.isOptimizedFrame());
+            assertFalse(frame.isInlinedFrame());
+          } else {
+            assertFalse(frame.isOptimizedFrame());
+            assertFalse(frame.isInlinedFrame());
+          }
+        }
+      }
+    }
+  }
+}
+
+function f() {
+  g();
+}
+
+function g() {
+  count++;
+  h();
+  var b = 1;  // Break point is set here.
+}
+
+function h() {
+  debugger;
+}
+
+f();f();f();
+%OptimizeFunctionOnNextCall(f);
+f();
+
+// Add the debug event listener.
+Debug.setListener(listener);
+
+f();
+
+assertEquals(5, count);
+assertEquals(2, break_count);
+
+// Get rid of the debug event listener.
+Debug.setListener(null);
diff --git a/test/mjsunit/debug-evaluate-locals-optimized-double.js b/test/mjsunit/debug-evaluate-locals-optimized-double.js
index 8447df5..9ed1dbb 100644
--- a/test/mjsunit/debug-evaluate-locals-optimized-double.js
+++ b/test/mjsunit/debug-evaluate-locals-optimized-double.js
@@ -50,12 +50,10 @@
           var expected_y = (i + 1) * 2 + 2 + ((i + 1) * 2 + 2) / 100;
 
           // All frames except the bottom one has normal variables a and b.
-          var a = ('a' === frame.localName(0)) ? 0 : 1;
-          var b = 1 - a;
-          assertEquals('a', frame.localName(a));
-          assertEquals('b', frame.localName(b));
-          assertEquals(expected_a, frame.localValue(a).value());
-          assertEquals(expected_b, frame.localValue(b).value());
+          assertEquals('a', frame.localName(0));
+          assertEquals('b', frame.localName(1));
+          assertEquals(expected_a, frame.localValue(0).value());
+          assertEquals(expected_b, frame.localValue(1).value());
 
           // All frames except the bottom one has arguments variables x and y.
           assertEquals('x', frame.argumentName(0));
diff --git a/test/mjsunit/debug-evaluate-locals-optimized.js b/test/mjsunit/debug-evaluate-locals-optimized.js
index c3cd5eb..683c139 100644
--- a/test/mjsunit/debug-evaluate-locals-optimized.js
+++ b/test/mjsunit/debug-evaluate-locals-optimized.js
@@ -50,12 +50,10 @@
           var expected_y = (i + 1) * 2 + 2;
 
           // All frames except the bottom one has normal variables a and b.
-          var a = ('a' === frame.localName(0)) ? 0 : 1;
-          var b = 1 - a;
-          assertEquals('a', frame.localName(a));
-          assertEquals('b', frame.localName(b));
-          assertEquals(expected_a, frame.localValue(a).value());
-          assertEquals(expected_b, frame.localValue(b).value());
+          assertEquals('a', frame.localName(0));
+          assertEquals('b', frame.localName(1));
+          assertEquals(expected_a, frame.localValue(0).value());
+          assertEquals(expected_b, frame.localValue(1).value());
 
           // All frames except the bottom one has arguments variables x and y.
           assertEquals('x', frame.argumentName(0));
@@ -121,7 +119,7 @@
       listenerComplete = true;
     }
   } catch (e) {
-    exception = e.stack;
+    exception = e
   };
 };
 
diff --git a/test/mjsunit/debug-scopes.js b/test/mjsunit/debug-scopes.js
index 1c23b0b..942bd2b 100644
--- a/test/mjsunit/debug-scopes.js
+++ b/test/mjsunit/debug-scopes.js
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// 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:
@@ -25,13 +25,12 @@
 // (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: --expose-debug-as debug
+// Flags: --expose-debug-as debug --allow-natives-syntax
 // The functions used for testing backtraces. They are at the top to make the
 // testing of source line/column easier.
 
-
 // Get the Debug object exposed from the debug context global object.
-Debug = debug.Debug;
+var Debug = debug.Debug;
 
 var test_name;
 var listener_delegate;
@@ -439,6 +438,26 @@
 EndTest();
 
 
+// With block in function that is marked for optimization while being executed.
+BeginTest("With 7");
+
+function with_7() {
+  with({}) {
+    %OptimizeFunctionOnNextCall(with_7);
+    debugger;
+  }
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.With,
+                   debug.ScopeType.Local,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({}, 0, exec_state);
+};
+with_7();
+EndTest();
+
+
 // Simple closure formed by returning an inner function referering the outer
 // functions arguments.
 BeginTest("Closure 1");
@@ -950,6 +969,28 @@
 EndTest();
 
 
+// Catch block in function that is marked for optimization while being executed.
+BeginTest("Catch block 7");
+function catch_block_7() {
+  %OptimizeFunctionOnNextCall(catch_block_7);
+  try {
+    throw 'Exception';
+  } catch (e) {
+    debugger;
+  }
+};
+
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Catch,
+                   debug.ScopeType.Local,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({e:'Exception'}, 0, exec_state);
+};
+catch_block_7();
+EndTest();
+
+
 assertEquals(begin_test_count, break_count,
              'one or more tests did not enter the debugger');
 assertEquals(begin_test_count, end_test_count,
diff --git a/test/mjsunit/debug-step-3.js b/test/mjsunit/debug-step-3.js
new file mode 100644
index 0000000..9cac0f5
--- /dev/null
+++ b/test/mjsunit/debug-step-3.js
@@ -0,0 +1,94 @@
+// 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: --expose-debug-as debug
+
+// This test tests that full code compiled without debug break slots
+// is recompiled with debug break slots when debugging is started.
+
+// Get the Debug object exposed from the debug context global object.
+Debug = debug.Debug
+
+var bp;
+var done = false;
+var step_count = 0;
+var set_bp = false
+
+// Debug event listener which steps until the global variable done is true.
+function listener(event, exec_state, event_data, data) {
+  if (event == Debug.DebugEvent.Break) {
+    if (!done) exec_state.prepareStep(Debug.StepAction.StepNext);
+    step_count++;
+  }
+};
+
+// Set the global variables state to prpare the stepping test.
+function prepare_step_test() {
+  done = false;
+  step_count = 0;
+}
+
+// Test function to step through.
+function f() {
+  var a = 0;
+  if (set_bp) { bp = Debug.setBreakPoint(f, 3); }
+  var i = 1;
+  var j = 2;
+  done = true;
+};
+
+prepare_step_test();
+f();
+
+// Add the debug event listener.
+Debug.setListener(listener);
+
+// Make f set a breakpoint with an activation on the stack.
+prepare_step_test();
+set_bp = true;
+f();
+// TODO(1782): Fix issue to bring back this assert.
+//assertEquals(4, step_count);
+Debug.clearBreakPoint(bp);
+
+// Set a breakpoint on the first var statement (line 1).
+set_bp = false;
+bp = Debug.setBreakPoint(f, 3);
+
+// Step through the function ensuring that the var statements are hit as well.
+prepare_step_test();
+f();
+assertEquals(4, step_count);
+
+// Clear the breakpoint and check that no stepping happens.
+Debug.clearBreakPoint(bp);
+prepare_step_test();
+f();
+assertEquals(0, step_count);
+
+// Get rid of the debug event listener.
+Debug.setListener(null);
diff --git a/test/mjsunit/debug-stepout-scope.js b/test/mjsunit/debug-stepout-scope.js
new file mode 100644
index 0000000..9c040da
--- /dev/null
+++ b/test/mjsunit/debug-stepout-scope.js
@@ -0,0 +1,423 @@
+// 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: --expose-debug-as debug --expose-natives-as=builtins
+
+// Check that the ScopeIterator can properly recreate the scope at
+// every point when stepping through functions.
+
+var Debug = debug.Debug;
+
+function listener(event, exec_state, event_data, data) {
+  if (event == Debug.DebugEvent.Break) {
+    // Access scope details.
+    var scope_count = exec_state.frame().scopeCount();
+    for (var i = 0; i < scope_count; i++) {
+      var scope = exec_state.frame().scope(i);
+      // assertTrue(scope.isScope());
+      scope.scopeType();
+      scope.scopeObject();
+    }
+
+    // Do steps until we reach the global scope again.
+    if (true) {
+      exec_state.prepareStep(Debug.StepAction.StepInMin, 1);
+    }
+  }
+}
+
+Debug.setListener(listener);
+
+
+function test1() {
+  debugger;
+  with ({x:1}) {
+    x = 2;
+  }
+}
+test1();
+
+
+function test2() {
+  if (true) {
+    with ({}) {
+      debugger;
+    }
+  } else {
+    with ({}) {
+      return 10;
+    }
+  }
+}
+test2();
+
+
+function test3() {
+  if (true) {
+    debugger;
+  } else {
+    with ({}) {
+      return 10;
+    }
+  }
+}
+test3();
+
+
+function test4() {
+  debugger;
+  with ({x:1}) x = 1
+}
+test4();
+
+
+function test5() {
+  debugger;
+  var dummy = 1;
+  with ({}) {
+    with ({}) {
+      dummy = 2;
+    }
+  }
+  dummy = 3;
+}
+test5();
+
+
+function test6() {
+  debugger;
+  try {
+    throw 'stuff';
+  } catch (e) {
+    e = 1;
+  }
+}
+test6();
+
+
+function test7() {
+  debugger;
+  function foo() {}
+}
+test7();
+
+
+function test8() {
+  debugger;
+  (function foo() {})();
+}
+test8();
+
+
+var q = 42;
+var prefixes = [ "debugger; ",
+                 "if (false) { try { throw 0; } catch(x) { return x; } }; debugger; " ];
+var bodies = [ "1",
+               "1 ",
+               "1;",
+               "1; ",
+               "q",
+               "q ",
+               "q;",
+               "q; ",
+               "try { throw 'stuff' } catch (e) { e = 1; }",
+               "try { throw 'stuff' } catch (e) { e = 1; } ",
+               "try { throw 'stuff' } catch (e) { e = 1; };",
+               "try { throw 'stuff' } catch (e) { e = 1; }; " ];
+var with_bodies = [ "with ({}) {}",
+                    "with ({x:1}) x",
+                    "with ({x:1}) x = 1",
+                    "with ({x:1}) x ",
+                    "with ({x:1}) x = 1 ",
+                    "with ({x:1}) x;",
+                    "with ({x:1}) x = 1;",
+                    "with ({x:1}) x; ",
+                    "with ({x:1}) x = 1; " ];
+
+
+function test9() {
+  debugger;
+  for (var i = 0; i < prefixes.length; ++i) {
+    var pre = prefixes[i];
+    for (var j = 0; j < bodies.length; ++j) {
+      var body = bodies[j];
+      eval(pre + body);
+      eval("'use strict'; " + pre + body);
+    }
+    for (var j = 0; j < with_bodies.length; ++j) {
+      var body = with_bodies[j];
+      eval(pre + body);
+    }
+  }
+}
+test9();
+
+
+function test10() {
+  debugger;
+  with ({}) {
+    return 10;
+  }
+}
+test10();
+
+
+function test11() {
+  debugger;
+  try {
+    throw 'stuff';
+  } catch (e) {
+    return 10;
+  }
+}
+test11();
+
+
+// Test global eval and function constructor.
+for (var i = 0; i < prefixes.length; ++i) {
+  var pre = prefixes[i];
+  for (var j = 0; j < bodies.length; ++j) {
+    var body = bodies[j];
+    eval(pre + body);
+    eval("'use strict'; " + pre + body);
+    Function(pre + body)();
+  }
+  for (var j = 0; j < with_bodies.length; ++j) {
+    var body = with_bodies[j];
+    eval(pre + body);
+    Function(pre + body)();
+  }
+}
+
+
+try {
+  with({}) {
+    debugger;
+    eval("{}$%:^");
+  }
+} catch(e) {
+  nop();
+}
+
+// Return from function constructed with Function constructor.
+var anon = 12;
+for (var i = 0; i < prefixes.length; ++i) {
+  var pre = prefixes[i];
+  Function(pre + "return 42")();
+  Function(pre + "return 42 ")();
+  Function(pre + "return 42;")();
+  Function(pre + "return 42; ")();
+  Function(pre + "return anon")();
+  Function(pre + "return anon ")();
+  Function(pre + "return anon;")();
+  Function(pre + "return anon; ")();
+}
+
+
+function nop() {}
+
+
+function stress() {
+  debugger;
+
+  L: with ({x:12}) {
+    break L;
+  }
+
+
+  with ({x: 'outer'}) {
+    label: {
+      with ({x: 'inner'}) {
+        break label;
+      }
+    }
+  }
+
+
+  with ({x: 'outer'}) {
+    label: {
+      with ({x: 'inner'}) {
+        break label;
+      }
+    }
+    nop();
+  }
+
+
+  with ({x: 'outer'}) {
+    label: {
+      with ({x: 'middle'}) {
+        with ({x: 'inner'}) {
+          break label;
+        }
+      }
+    }
+  }
+
+
+  with ({x: 'outer'}) {
+    label: {
+      with ({x: 'middle'}) {
+        with ({x: 'inner'}) {
+          break label;
+        }
+      }
+    }
+    nop();
+  }
+
+
+  with ({x: 'outer'}) {
+    for (var i = 0; i < 3; ++i) {
+      with ({x: 'inner' + i}) {
+        continue;
+      }
+    }
+  }
+
+
+  with ({x: 'outer'}) {
+    label: for (var i = 0; i < 3; ++i) {
+      with ({x: 'middle' + i}) {
+        for (var j = 0; j < 3; ++j) {
+          with ({x: 'inner' + j}) {
+            continue label;
+          }
+        }
+      }
+    }
+  }
+
+
+  with ({x: 'outer'}) {
+    try {
+      with ({x: 'inner'}) {
+        throw 0;
+      }
+    } catch (e) {
+    }
+  }
+
+
+  with ({x: 'outer'}) {
+    try {
+      with ({x: 'inner'}) {
+        throw 0;
+      }
+    } catch (e) {
+      nop();
+    }
+  }
+
+
+  with ({x: 'outer'}) {
+    try {
+      with ({x: 'middle'}) {
+        with ({x: 'inner'}) {
+          throw 0;
+        }
+      }
+    } catch (e) {
+    }
+  }
+
+
+  try {
+    with ({x: 'outer'}) {
+      try {
+        with ({x: 'inner'}) {
+          throw 0;
+        }
+      } finally {
+      }
+    }
+  } catch (e) {
+  }
+
+
+  try {
+    with ({x: 'outer'}) {
+      try {
+        with ({x: 'inner'}) {
+          throw 0;
+        }
+      } finally {
+        nop();
+      }
+    }
+  } catch (e) {
+  }
+
+
+  function stress1() {
+    with ({x:12}) {
+      return x;
+    }
+  }
+  stress1();
+
+
+  function stress2() {
+    with ({x: 'outer'}) {
+      with ({x: 'inner'}) {
+        return x;
+      }
+    }
+  }
+  stress2();
+
+  function stress3() {
+    try {
+      with ({x: 'inner'}) {
+        throw 0;
+      }
+    } catch (e) {
+      return e;
+    }
+  }
+  stress3();
+
+
+  function stress4() {
+    try {
+      with ({x: 'inner'}) {
+        throw 0;
+      }
+    } catch (e) {
+      with ({x: 'inner'}) {
+        return e;
+      }
+    }
+  }
+  stress4();
+
+}
+stress();
+
+
+// With block as the last(!) statement in global code.
+with ({}) { debugger; }
\ No newline at end of file
diff --git a/test/mjsunit/element-kind.js b/test/mjsunit/element-kind.js
deleted file mode 100644
index 48a029f..0000000
--- a/test/mjsunit/element-kind.js
+++ /dev/null
@@ -1,102 +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: --allow-natives-syntax
-// Test element kind of objects
-
-var element_kind = {
-  fast_elements                     :  1,
-  fast_double_elements              :  2,
-  dictionary_elements               :  3,
-  external_byte_elements            :  4,
-  external_unsigned_byte_elements   :  5,
-  external_short_elements           :  6,
-  external_unsigned_short_elements  :  7,
-  external_int_elements             :  8,
-  external_unsigned_int_elements    :  9,
-  external_float_elements           : 10,
-  external_double_elements          : 11,
-  external_pixel_elements           : 12
-}
-
-// We expect an object to only be of one element kind.
-function assertKind(expected, obj){
-  assertEquals(expected == element_kind.fast_elements,
-               %HasFastElements(obj));
-  assertEquals(expected == element_kind.fast_double_elements,
-               %HasFastDoubleElements(obj));
-  assertEquals(expected == element_kind.dictionary_elements,
-               %HasDictionaryElements(obj));
-  assertEquals(expected == element_kind.external_byte_elements,
-               %HasExternalByteElements(obj));
-  assertEquals(expected == element_kind.external_unsigned_byte_elements,
-               %HasExternalUnsignedByteElements(obj));
-  assertEquals(expected == element_kind.external_short_elements,
-               %HasExternalShortElements(obj));
-  assertEquals(expected == element_kind.external_unsigned_short_elements,
-               %HasExternalUnsignedShortElements(obj));
-  assertEquals(expected == element_kind.external_int_elements,
-               %HasExternalIntElements(obj));
-  assertEquals(expected == element_kind.external_unsigned_int_elements,
-               %HasExternalUnsignedIntElements(obj));
-  assertEquals(expected == element_kind.external_float_elements,
-               %HasExternalFloatElements(obj));
-  assertEquals(expected == element_kind.external_double_elements,
-               %HasExternalDoubleElements(obj));
-  assertEquals(expected == element_kind.external_pixel_elements,
-               %HasExternalPixelElements(obj));
-  // every external kind is also an external array
-  assertEquals(expected >= element_kind.external_byte_elements,
-               %HasExternalArrayElements(obj));
-}
-
-var me = {};
-assertKind(element_kind.fast_elements, me);
-me.dance = 0xD15C0;
-me.drink = 0xC0C0A;
-assertKind(element_kind.fast_elements, me);
-
-var you = new Array();
-for(i = 0; i < 1337; i++) {
-  you[i] = i;
-}
-assertKind(element_kind.fast_elements, you);
-
-assertKind(element_kind.dictionary_elements, new Array(0xC0C0A));
-
-// fast_double_elements not yet available
-
-
-assertKind(element_kind.external_byte_elements,           new Int8Array(9001));
-assertKind(element_kind.external_unsigned_byte_elements,  new Uint8Array(007));
-assertKind(element_kind.external_short_elements,          new Int16Array(666));
-assertKind(element_kind.external_unsigned_short_elements, new Uint16Array(42));
-assertKind(element_kind.external_int_elements,            new Int32Array(0xF));
-assertKind(element_kind.external_unsigned_int_elements,   new Uint32Array(23));
-assertKind(element_kind.external_float_elements,          new Float32Array(7));
-assertKind(element_kind.external_double_elements,         new Float64Array(0));
-assertKind(element_kind.external_pixel_elements,          new PixelArray(512));
diff --git a/test/mjsunit/cyclic-error-to-string.js b/test/mjsunit/elements-kind-depends.js
similarity index 68%
copy from test/mjsunit/cyclic-error-to-string.js
copy to test/mjsunit/elements-kind-depends.js
index 2502b53..82f188b 100644
--- a/test/mjsunit/cyclic-error-to-string.js
+++ b/test/mjsunit/elements-kind-depends.js
@@ -25,22 +25,50 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Test printing of cyclic errors which return the empty string for
-// compatibility with Safari and Firefox.
+// Flags: --allow-natives-syntax --smi-only-arrays
 
-var e = new Error();
-assertEquals('Error', e + '');
+function burn() {
+  var a = new Array(3);
+  a[0] = 10;
+  a[1] = 15.5;
+  a[2] = 20;
+  return a;
+}
 
-e = new Error();
-e.name = e;
-e.message = e;
-e.stack = e;
-e.arguments = e;
-assertEquals(': ', e + '');
+function check(a) {
+  assertEquals(10, a[0]);
+  assertEquals(15.5, a[1]);
+  assertEquals(20, a[2]);
+}
 
-e = new Error();
-e.name = [ e ];
-e.message = [ e ];
-e.stack = [ e ];
-e.arguments = [ e ];
-assertEquals(': ', e + '');
+var b;
+for (var i = 0; i < 3; ++i) {
+  b = burn();
+  check(b);  // all OK
+}
+%OptimizeFunctionOnNextCall(burn);
+b = burn();
+check(b);  // fails
+
+
+function loop_test(x) {
+  for (i=0;i<3;i++) {
+    x[i] = (i+1) * 0.5;
+  }
+}
+
+function check2(b) {
+  assertEquals(0.5, b[0]);
+  assertEquals(1.0, b[1]);
+  assertEquals(1.5, b[2]);
+}
+
+for (var i = 0; i < 3; ++i) {
+  b = [0,1,2];
+  loop_test(b);
+  check2(b);
+}
+%OptimizeFunctionOnNextCall(loop_test);
+b = [0,1,2];
+loop_test(b);
+check2(b);
diff --git a/test/mjsunit/elements-kind.js b/test/mjsunit/elements-kind.js
new file mode 100644
index 0000000..8a8a3c7
--- /dev/null
+++ b/test/mjsunit/elements-kind.js
@@ -0,0 +1,340 @@
+// 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: --allow-natives-syntax --smi-only-arrays --expose-gc
+
+// Test element kind of objects.
+// Since --smi-only-arrays affects builtins, its default setting at compile
+// time sticks if built with snapshot.  If --smi-only-arrays is deactivated
+// by default, only a no-snapshot build actually has smi-only arrays enabled
+// in this test case.  Depending on whether smi-only arrays are actually
+// enabled, this test takes the appropriate code path to check smi-only arrays.
+
+support_smi_only_arrays = %HasFastSmiOnlyElements([]);
+
+if (support_smi_only_arrays) {
+  print("Tests include smi-only arrays.");
+} else {
+  print("Tests do NOT include smi-only arrays.");
+}
+
+var elements_kind = {
+  fast_smi_only            :  'fast smi only elements',
+  fast                     :  'fast elements',
+  fast_double              :  'fast double elements',
+  dictionary               :  'dictionary elements',
+  external_byte            :  'external byte elements',
+  external_unsigned_byte   :  'external unsigned byte elements',
+  external_short           :  'external short elements',
+  external_unsigned_short  :  'external unsigned short elements',
+  external_int             :  'external int elements',
+  external_unsigned_int    :  'external unsigned int elements',
+  external_float           :  'external float elements',
+  external_double          :  'external double elements',
+  external_pixel           :  'external pixel elements'
+}
+
+function getKind(obj) {
+  if (%HasFastSmiOnlyElements(obj)) return elements_kind.fast_smi_only;
+  if (%HasFastElements(obj)) return elements_kind.fast;
+  if (%HasFastDoubleElements(obj)) return elements_kind.fast_double;
+  if (%HasDictionaryElements(obj)) return elements_kind.dictionary;
+  // Every external kind is also an external array.
+  assertTrue(%HasExternalArrayElements(obj));
+  if (%HasExternalByteElements(obj)) {
+    return elements_kind.external_byte;
+  }
+  if (%HasExternalUnsignedByteElements(obj)) {
+    return elements_kind.external_unsigned_byte;
+  }
+  if (%HasExternalShortElements(obj)) {
+    return elements_kind.external_short;
+  }
+  if (%HasExternalUnsignedShortElements(obj)) {
+    return elements_kind.external_unsigned_short;
+  }
+  if (%HasExternalIntElements(obj)) {
+    return elements_kind.external_int;
+  }
+  if (%HasExternalUnsignedIntElements(obj)) {
+    return elements_kind.external_unsigned_int;
+  }
+  if (%HasExternalFloatElements(obj)) {
+    return elements_kind.external_float;
+  }
+  if (%HasExternalDoubleElements(obj)) {
+    return elements_kind.external_double;
+  }
+  if (%HasExternalPixelElements(obj)) {
+    return elements_kind.external_pixel;
+  }
+}
+
+function assertKind(expected, obj, name_opt) {
+  if (!support_smi_only_arrays &&
+      expected == elements_kind.fast_smi_only) {
+    expected = elements_kind.fast;
+  }
+  assertEquals(expected, getKind(obj), name_opt);
+}
+
+var me = {};
+assertKind(elements_kind.fast, me);
+me.dance = 0xD15C0;
+me.drink = 0xC0C0A;
+assertKind(elements_kind.fast, me);
+
+var too = [1,2,3];
+assertKind(elements_kind.fast_smi_only, too);
+too.dance = 0xD15C0;
+too.drink = 0xC0C0A;
+assertKind(elements_kind.fast_smi_only, too);
+
+// Make sure the element kind transitions from smionly when a non-smi is stored.
+var you = new Array();
+assertKind(elements_kind.fast_smi_only, you);
+for (var i = 0; i < 1337; i++) {
+  var val = i;
+  if (i == 1336) {
+    assertKind(elements_kind.fast_smi_only, you);
+    val = new Object();
+  }
+  you[i] = val;
+}
+assertKind(elements_kind.fast, you);
+
+assertKind(elements_kind.dictionary, new Array(0xDECAF));
+
+var fast_double_array = new Array(0xDECAF);
+for (var i = 0; i < 0xDECAF; i++) fast_double_array[i] = i / 2;
+assertKind(elements_kind.fast_double, fast_double_array);
+
+assertKind(elements_kind.external_byte,           new Int8Array(9001));
+assertKind(elements_kind.external_unsigned_byte,  new Uint8Array(007));
+assertKind(elements_kind.external_short,          new Int16Array(666));
+assertKind(elements_kind.external_unsigned_short, new Uint16Array(42));
+assertKind(elements_kind.external_int,            new Int32Array(0xF));
+assertKind(elements_kind.external_unsigned_int,   new Uint32Array(23));
+assertKind(elements_kind.external_float,          new Float32Array(7));
+assertKind(elements_kind.external_double,         new Float64Array(0));
+assertKind(elements_kind.external_pixel,          new PixelArray(512));
+
+// Crankshaft support for smi-only array elements.
+function monomorphic(array) {
+  for (var i = 0; i < 3; i++) {
+    array[i] = i + 10;
+  }
+  assertKind(elements_kind.fast_smi_only, array);
+  for (var i = 0; i < 3; i++) {
+    var a = array[i];
+    assertEquals(i + 10, a);
+  }
+}
+var smi_only = [1, 2, 3];
+for (var i = 0; i < 3; i++) monomorphic(smi_only);
+%OptimizeFunctionOnNextCall(monomorphic);
+monomorphic(smi_only);
+
+if (support_smi_only_arrays) {
+  function construct_smis() {
+    var a = [0, 0, 0];
+    a[0] = 0;  // Send the COW array map to the steak house.
+    assertKind(elements_kind.fast_smi_only, a);
+    return a;
+  }
+  function construct_doubles() {
+    var a = construct_smis();
+    a[0] = 1.5;
+    assertKind(elements_kind.fast_double, a);
+    return a;
+  }
+  function construct_objects() {
+    var a = construct_smis();
+    a[0] = "one";
+    assertKind(elements_kind.fast, a);
+    return a;
+  }
+
+  // Test crankshafted transition SMI->DOUBLE.
+  function convert_to_double(array) {
+    array[1] = 2.5;
+    assertKind(elements_kind.fast_double, array);
+    assertEquals(2.5, array[1]);
+  }
+  var smis = construct_smis();
+  for (var i = 0; i < 3; i++) convert_to_double(smis);
+  %OptimizeFunctionOnNextCall(convert_to_double);
+  smis = construct_smis();
+  convert_to_double(smis);
+  // Test crankshafted transitions SMI->FAST and DOUBLE->FAST.
+  function convert_to_fast(array) {
+    array[1] = "two";
+    assertKind(elements_kind.fast, array);
+    assertEquals("two", array[1]);
+  }
+  smis = construct_smis();
+  for (var i = 0; i < 3; i++) convert_to_fast(smis);
+  var doubles = construct_doubles();
+  for (var i = 0; i < 3; i++) convert_to_fast(doubles);
+  smis = construct_smis();
+  doubles = construct_doubles();
+  %OptimizeFunctionOnNextCall(convert_to_fast);
+  convert_to_fast(smis);
+  convert_to_fast(doubles);
+  // Test transition chain SMI->DOUBLE->FAST (crankshafted function will
+  // transition to FAST directly).
+  function convert_mixed(array, value, kind) {
+    array[1] = value;
+    assertKind(kind, array);
+    assertEquals(value, array[1]);
+  }
+  smis = construct_smis();
+  for (var i = 0; i < 3; i++) {
+    convert_mixed(smis, 1.5, elements_kind.fast_double);
+  }
+  doubles = construct_doubles();
+  for (var i = 0; i < 3; i++) {
+    convert_mixed(doubles, "three", elements_kind.fast);
+  }
+  smis = construct_smis();
+  doubles = construct_doubles();
+  %OptimizeFunctionOnNextCall(convert_mixed);
+  convert_mixed(smis, 1, elements_kind.fast);
+  convert_mixed(doubles, 1, elements_kind.fast);
+  assertTrue(%HaveSameMap(smis, doubles));
+}
+
+// Crankshaft support for smi-only elements in dynamic array literals.
+function get(foo) { return foo; }  // Used to generate dynamic values.
+
+function crankshaft_test() {
+  var a = [get(1), get(2), get(3)];
+  assertKind(elements_kind.fast_smi_only, a);
+  var b = [get(1), get(2), get("three")];
+  assertKind(elements_kind.fast, b);
+  var c = [get(1), get(2), get(3.5)];
+  if (support_smi_only_arrays) {
+    assertKind(elements_kind.fast_double, c);
+  } else {
+    assertKind(elements_kind.fast, c);
+  }
+}
+for (var i = 0; i < 3; i++) {
+  crankshaft_test();
+}
+%OptimizeFunctionOnNextCall(crankshaft_test);
+crankshaft_test();
+
+// Elements_kind transitions for arrays.
+
+// A map can have three different elements_kind transitions: SMI->DOUBLE,
+// DOUBLE->OBJECT, and SMI->OBJECT. No matter in which order these three are
+// created, they must always end up with the same FAST map.
+
+// This test is meaningless without FAST_SMI_ONLY_ELEMENTS.
+if (support_smi_only_arrays) {
+  // Preparation: create one pair of identical objects for each case.
+  var a = [1, 2, 3];
+  var b = [1, 2, 3];
+  assertTrue(%HaveSameMap(a, b));
+  assertKind(elements_kind.fast_smi_only, a);
+  var c = [1, 2, 3];
+  c["case2"] = true;
+  var d = [1, 2, 3];
+  d["case2"] = true;
+  assertTrue(%HaveSameMap(c, d));
+  assertFalse(%HaveSameMap(a, c));
+  assertKind(elements_kind.fast_smi_only, c);
+  var e = [1, 2, 3];
+  e["case3"] = true;
+  var f = [1, 2, 3];
+  f["case3"] = true;
+  assertTrue(%HaveSameMap(e, f));
+  assertFalse(%HaveSameMap(a, e));
+  assertFalse(%HaveSameMap(c, e));
+  assertKind(elements_kind.fast_smi_only, e);
+  // Case 1: SMI->DOUBLE, DOUBLE->OBJECT, SMI->OBJECT.
+  a[0] = 1.5;
+  assertKind(elements_kind.fast_double, a);
+  a[0] = "foo";
+  assertKind(elements_kind.fast, a);
+  b[0] = "bar";
+  assertTrue(%HaveSameMap(a, b));
+  // Case 2: SMI->DOUBLE, SMI->OBJECT, DOUBLE->OBJECT.
+  c[0] = 1.5;
+  assertKind(elements_kind.fast_double, c);
+  assertFalse(%HaveSameMap(c, d));
+  d[0] = "foo";
+  assertKind(elements_kind.fast, d);
+  assertFalse(%HaveSameMap(c, d));
+  c[0] = "bar";
+  assertTrue(%HaveSameMap(c, d));
+  // Case 3: SMI->OBJECT, SMI->DOUBLE, DOUBLE->OBJECT.
+  e[0] = "foo";
+  assertKind(elements_kind.fast, e);
+  assertFalse(%HaveSameMap(e, f));
+  f[0] = 1.5;
+  assertKind(elements_kind.fast_double, f);
+  assertFalse(%HaveSameMap(e, f));
+  f[0] = "bar";
+  assertKind(elements_kind.fast, f);
+  assertTrue(%HaveSameMap(e, f));
+}
+
+// Test if Array.concat() works correctly with DOUBLE elements.
+if (support_smi_only_arrays) {
+  var a = [1, 2];
+  assertKind(elements_kind.fast_smi_only, a);
+  var b = [4.5, 5.5];
+  assertKind(elements_kind.fast_double, b);
+  var c = a.concat(b);
+  assertEquals([1, 2, 4.5, 5.5], c);
+  // TODO(1810): Change implementation so that we get DOUBLE elements here?
+  assertKind(elements_kind.fast, c);
+}
+
+// Test that Array.push() correctly handles SMI elements.
+if (support_smi_only_arrays) {
+  var a = [1, 2];
+  assertKind(elements_kind.fast_smi_only, a);
+  a.push(3, 4, 5);
+  assertKind(elements_kind.fast_smi_only, a);
+  assertEquals([1, 2, 3, 4, 5], a);
+}
+
+// Test that Array.splice() and Array.slice() return correct ElementsKinds.
+if (support_smi_only_arrays) {
+  var a = ["foo", "bar"];
+  assertKind(elements_kind.fast, a);
+  var b = a.splice(0, 1);
+  assertKind(elements_kind.fast, b);
+  var c = a.slice(0, 1);
+  assertKind(elements_kind.fast, c);
+}
+
+// Throw away type information in the ICs for next stress run.
+gc();
diff --git a/test/mjsunit/elements-transition.js b/test/mjsunit/elements-transition.js
new file mode 100644
index 0000000..5f6cc4f
--- /dev/null
+++ b/test/mjsunit/elements-transition.js
@@ -0,0 +1,107 @@
+// 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: --allow-natives-syntax --smi-only-arrays
+
+support_smi_only_arrays = %HasFastSmiOnlyElements([]);
+
+if (support_smi_only_arrays) {
+  function test(test_double, test_object, set, length) {
+    // We apply the same operations to two identical arrays.  The first array
+    // triggers an IC miss, upon which the conversion stub is generated, but the
+    // actual conversion is done in runtime.  The second array, arriving at
+    // the previously patched IC, is then converted using the conversion stub.
+    var array_1 = new Array(length);
+    var array_2 = new Array(length);
+
+    assertTrue(%HasFastSmiOnlyElements(array_1));
+    assertTrue(%HasFastSmiOnlyElements(array_2));
+    for (var i = 0; i < length; i++) {
+      if (i == length - 5 && test_double) {
+        // Trigger conversion to fast double elements at length-5.
+        set(array_1, i, 0.5);
+        set(array_2, i, 0.5);
+        assertTrue(%HasFastDoubleElements(array_1));
+        assertTrue(%HasFastDoubleElements(array_2));
+      } else if (i == length - 3 && test_object) {
+        // Trigger conversion to fast object elements at length-3.
+        set(array_1, i, 'object');
+        set(array_2, i, 'object');
+        assertTrue(%HasFastElements(array_1));
+        assertTrue(%HasFastElements(array_2));
+      } else if (i != length - 7) {
+        // Set the element to an integer but leave a hole at length-7.
+        set(array_1, i, 2*i+1);
+        set(array_2, i, 2*i+1);
+      }
+    }
+
+    for (var i = 0; i < length; i++) {
+      if (i == length - 5 && test_double) {
+        assertEquals(0.5, array_1[i]);
+        assertEquals(0.5, array_2[i]);
+      } else if (i == length - 3 && test_object) {
+        assertEquals('object', array_1[i]);
+        assertEquals('object', array_2[i]);
+      } else if (i != length - 7) {
+        assertEquals(2*i+1, array_1[i]);
+        assertEquals(2*i+1, array_2[i]);
+      } else {
+        assertEquals(undefined, array_1[i]);
+        assertEquals(undefined, array_2[i]);
+      }
+    }
+
+    assertEquals(length, array_1.length);
+    assertEquals(length, array_2.length);
+  }
+
+  test(false, false, function(a,i,v){ a[i] = v; }, 20);
+  test(true,  false, function(a,i,v){ a[i] = v; }, 20);
+  test(false, true,  function(a,i,v){ a[i] = v; }, 20);
+  test(true,  true,  function(a,i,v){ a[i] = v; }, 20);
+
+  test(false, false, function(a,i,v){ a[i] = v; }, 10000);
+  test(true,  false, function(a,i,v){ a[i] = v; }, 10000);
+  test(false, true,  function(a,i,v){ a[i] = v; }, 10000);
+  test(true,  true,  function(a,i,v){ a[i] = v; }, 10000);
+
+  // Check COW arrays
+  function get_cow() { return [1, 2, 3]; }
+
+  function transition(x) { x[0] = 1.5; }
+
+  var ignore = get_cow();
+  transition(ignore);  // Handled by runtime.
+  var a = get_cow();
+  var b = get_cow();
+  transition(a);  // Handled by IC.
+  assertEquals(1.5, a[0]);
+  assertEquals(1, b[0]);
+} else {
+  print("Test skipped because smi only arrays are not supported.");
+}
\ No newline at end of file
diff --git a/test/mjsunit/error-tostring.js b/test/mjsunit/error-tostring.js
new file mode 100644
index 0000000..a285641
--- /dev/null
+++ b/test/mjsunit/error-tostring.js
@@ -0,0 +1,85 @@
+// 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.
+
+
+// Test default string representation of an Error object.
+
+var e = new Error();
+assertEquals('Error', e.toString());
+
+
+// Test printing of cyclic errors which return the empty string for
+// compatibility with Safari and Firefox.
+
+e = new Error();
+e.name = e;
+e.message = e;
+e.stack = "Does not occur in output";
+e.arguments = "Does not occur in output";
+e.type = "Does not occur in output";
+assertEquals('', e.toString());
+
+e = new Error();
+e.name = [ e ];
+e.message = [ e ];
+e.stack = "Does not occur in output";
+e.arguments = "Does not occur in output";
+e.type = "Does not occur in output";
+assertEquals('', e.toString());
+
+
+// Test the sequence in which getters and toString operations are called
+// on a given Error object.  Verify the produced string representation.
+
+function testErrorToString(nameValue, messageValue) {
+  var seq = [];
+  var e = {
+    get name() {
+      seq.push(1);
+      return (nameValue === undefined) ? nameValue : {
+        toString: function() { seq.push(2); return nameValue; }
+      };
+    },
+    get message() {
+      seq.push(3);
+      return (messageValue === undefined) ? messageValue : {
+        toString: function() { seq.push(4); return messageValue; }
+      };
+    }
+  };
+  var string = Error.prototype.toString.call(e);
+  return [string,seq];
+}
+
+assertEquals(["Error",[1,3]], testErrorToString(undefined, undefined));
+assertEquals(["e1",[1,2,3]], testErrorToString("e1", undefined));
+assertEquals(["e1: null",[1,2,3,4]], testErrorToString("e1", null));
+assertEquals(["e1",[1,2,3,4]], testErrorToString("e1", ""));
+assertEquals(["Error: e2",[1,3,4]], testErrorToString(undefined, "e2"));
+assertEquals(["null: e2",[1,2,3,4]], testErrorToString(null, "e2"));
+assertEquals(["e2",[1,2,3,4]], testErrorToString("", "e2"));
+assertEquals(["e1: e2",[1,2,3,4]], testErrorToString("e1", "e2"));
diff --git a/test/mjsunit/eval.js b/test/mjsunit/eval.js
index b6284ba..100f216 100644
--- a/test/mjsunit/eval.js
+++ b/test/mjsunit/eval.js
@@ -39,7 +39,7 @@
 
 try {
   eval('hest 7 &*^*&^');
-  assertTrue(false, 'Did not throw on syntax error.');
+  assertUnreachable('Did not throw on syntax error.');
 } catch (e) {
   assertEquals('SyntaxError', e.name);
 }
@@ -108,6 +108,7 @@
 result =
   (function() {
     var foo = 2;
+    // Should be non-direct call.
     return x.eval('foo');
   })();
 assertEquals(0, result);
@@ -115,12 +116,33 @@
 foo = 0;
 result =
   (function() {
+    var foo = 2;
+    // Should be non-direct call.
+    return (1,eval)('foo');
+  })();
+assertEquals(0, result);
+
+foo = 0;
+result =
+  (function() {
     var eval = function(x) { return x; };
     var foo = eval(2);
+    // Should be non-direct call.
     return e('foo');
   })();
 assertEquals(0, result);
 
+foo = 0;
+result =
+  (function() {
+    var foo = 2;
+    // Should be direct call.
+    with ({ eval : e }) {
+      return eval('foo');
+    }
+  })();
+assertEquals(2, result);
+
 result =
   (function() {
     var eval = function(x) { return 2 * x; };
@@ -135,19 +157,17 @@
   })();
 assertEquals(this, result);
 
-result =
-  (function() {
-    var obj = { f: function(eval) { return eval("this"); } };
-    return obj.f(eval);
-  })();
-assertEquals(this, result);
+(function() {
+  var obj = { f: function(eval) { return eval("this"); } };
+  result = obj.f(eval);
+  assertEquals(obj, result);
+})();
 
-result =
-  (function() {
-    var obj = { f: function(eval) { arguments; return eval("this"); } };
-    return obj.f(eval);
-  })();
-assertEquals(this, result);
+(function() {
+  var obj = { f: function(eval) { arguments; return eval("this"); } };
+  result = obj.f(eval);
+  assertEquals(obj, result);
+})();
 
 eval = function(x) { return 2 * x; };
 result =
@@ -156,6 +176,9 @@
   })();
 assertEquals(4, result);
 
+
+
+
 // Regression test: calling a function named eval found in a context that is
 // not the global context should get the global object as receiver.
 result =
diff --git a/test/mjsunit/function-bind.js b/test/mjsunit/function-bind.js
index e9d0221..4a8f2d2 100644
--- a/test/mjsunit/function-bind.js
+++ b/test/mjsunit/function-bind.js
@@ -29,29 +29,31 @@
 
 // Simple tests.
 function foo(x, y, z) {
-  return x + y + z;
+  return [this, arguments.length, x];
 }
 
+assertEquals(3, foo.length);
+
 var f = foo.bind(foo);
-assertEquals(3, f(1, 1, 1));
+assertEquals([foo, 3, 1], f(1, 2, 3));
 assertEquals(3, f.length);
 
-f = foo.bind(foo, 2);
-assertEquals(4, f(1, 1));
+f = foo.bind(foo, 1);
+assertEquals([foo, 3, 1], f(2, 3));
 assertEquals(2, f.length);
 
-f = foo.bind(foo, 2, 2);
-assertEquals(5, f(1));
+f = foo.bind(foo, 1, 2);
+assertEquals([foo, 3, 1], f(3));
 assertEquals(1, f.length);
 
-f = foo.bind(foo, 2, 2, 2);
-assertEquals(6, f());
+f = foo.bind(foo, 1, 2, 3);
+assertEquals([foo, 3, 1], f());
 assertEquals(0, f.length);
 
 // Test that length works correctly even if more than the actual number
 // of arguments are given when binding.
 f = foo.bind(foo, 1, 2, 3, 4, 5, 6, 7, 8, 9);
-assertEquals(6, f());
+assertEquals([foo, 9, 1], f());
 assertEquals(0, f.length);
 
 // Use a different bound object.
@@ -78,65 +80,98 @@
 // When only giving the thisArg, any number of binds should have
 // the same effect.
 f = foo.bind(foo);
-assertEquals(3, f(1, 1, 1));
-f = foo.bind(foo).bind(foo).bind(foo).bind(foo);
-assertEquals(3, f(1, 1, 1));
+assertEquals([foo, 3, 1], f(1, 2, 3));
+
+var not_foo = {};
+f = foo.bind(foo).bind(not_foo).bind(not_foo).bind(not_foo);
+assertEquals([foo, 3, 1], f(1, 2, 3));
 assertEquals(3, f.length);
 
 // Giving bound parameters should work at any place in the chain.
-f = foo.bind(foo, 1).bind(foo).bind(foo).bind(foo);
-assertEquals(3, f(1, 1));
+f = foo.bind(foo, 1).bind(not_foo).bind(not_foo).bind(not_foo);
+assertEquals([foo, 3, 1], f(2, 3));
 assertEquals(2, f.length);
 
-f = foo.bind(foo).bind(foo, 1).bind(foo).bind(foo);
-assertEquals(3, f(1, 1));
+f = foo.bind(foo).bind(not_foo, 1).bind(not_foo).bind(not_foo);
+assertEquals([foo, 3, 1], f(2, 3));
 assertEquals(2, f.length);
 
-f = foo.bind(foo).bind(foo).bind(foo,1 ).bind(foo);
-assertEquals(3, f(1, 1));
+f = foo.bind(foo).bind(not_foo).bind(not_foo,1 ).bind(not_foo);
+assertEquals([foo, 3, 1], f(2, 3));
 assertEquals(2, f.length);
 
-f = foo.bind(foo).bind(foo).bind(foo).bind(foo, 1);
-assertEquals(3, f(1, 1));
+f = foo.bind(foo).bind(not_foo).bind(not_foo).bind(not_foo, 1);
+assertEquals([foo, 3, 1], f(2, 3));
 assertEquals(2, f.length);
 
-// Several parameters can be given, and given in different bind invokations.
-f = foo.bind(foo, 1, 1).bind(foo).bind(foo).bind(foo);
-assertEquals(3, f(1));
+// Several parameters can be given, and given in different bind invocations.
+f = foo.bind(foo, 1, 2).bind(not_foo).bind(not_foo).bind(not_foo);
+assertEquals([foo, 3, 1], f(3));
 assertEquals(1, f.length);
 
-f = foo.bind(foo).bind(foo, 1, 1).bind(foo).bind(foo);
-assertEquals(3, f(1));
+f = foo.bind(foo).bind(not_foo, 1, 2).bind(not_foo).bind(not_foo);
+assertEquals([foo, 3, 1], f(1));
 assertEquals(1, f.length);
 
-f = foo.bind(foo).bind(foo, 1, 1).bind(foo).bind(foo);
-assertEquals(3, f(1));
+f = foo.bind(foo).bind(not_foo, 1, 2).bind(not_foo).bind(not_foo);
+assertEquals([foo, 3, 1], f(3));
 assertEquals(1, f.length);
 
-f = foo.bind(foo).bind(foo).bind(foo, 1, 1).bind(foo);
-assertEquals(3, f(1));
+f = foo.bind(foo).bind(not_foo).bind(not_foo, 1, 2).bind(not_foo);
+assertEquals([foo, 3, 1], f(1));
 assertEquals(1, f.length);
 
-f = foo.bind(foo).bind(foo).bind(foo).bind(foo, 1, 1);
-assertEquals(3, f(1));
+f = foo.bind(foo).bind(not_foo).bind(not_foo).bind(not_foo, 1, 2);
+assertEquals([foo, 3, 1], f(3));
 assertEquals(1, f.length);
 
-f = foo.bind(foo, 1).bind(foo, 1).bind(foo).bind(foo);
-assertEquals(3, f(1));
+f = foo.bind(foo, 1).bind(not_foo, 2).bind(not_foo).bind(not_foo);
+assertEquals([foo, 3, 1], f(3));
 assertEquals(1, f.length);
 
-f = foo.bind(foo, 1).bind(foo).bind(foo, 1).bind(foo);
-assertEquals(3, f(1));
+f = foo.bind(foo, 1).bind(not_foo).bind(not_foo, 2).bind(not_foo);
+assertEquals([foo, 3, 1], f(3));
 assertEquals(1, f.length);
 
-f = foo.bind(foo, 1).bind(foo).bind(foo).bind(foo, 1);
-assertEquals(3, f(1));
+f = foo.bind(foo, 1).bind(not_foo).bind(not_foo).bind(not_foo, 2);
+assertEquals([foo, 3, 1], f(3));
 assertEquals(1, f.length);
 
-f = foo.bind(foo).bind(foo, 1).bind(foo).bind(foo, 1);
-assertEquals(3, f(1));
+f = foo.bind(foo).bind(not_foo, 1).bind(not_foo).bind(not_foo, 2);
+assertEquals([foo, 3, 1], f(3));
 assertEquals(1, f.length);
 
+// The wrong number of arguments can be given to bound functions too.
+f = foo.bind(foo);
+assertEquals(3, f.length);
+assertEquals([foo, 0, undefined], f());
+assertEquals([foo, 1, 1], f(1));
+assertEquals([foo, 2, 1], f(1, 2));
+assertEquals([foo, 3, 1], f(1, 2, 3));
+assertEquals([foo, 4, 1], f(1, 2, 3, 4));
+
+f = foo.bind(foo, 1);
+assertEquals(2, f.length);
+assertEquals([foo, 1, 1], f());
+assertEquals([foo, 2, 1], f(2));
+assertEquals([foo, 3, 1], f(2, 3));
+assertEquals([foo, 4, 1], f(2, 3, 4));
+
+f = foo.bind(foo, 1, 2);
+assertEquals(1, f.length);
+assertEquals([foo, 2, 1], f());
+assertEquals([foo, 3, 1], f(3));
+assertEquals([foo, 4, 1], f(3, 4));
+
+f = foo.bind(foo, 1, 2, 3);
+assertEquals(0, f.length);
+assertEquals([foo, 3, 1], f());
+assertEquals([foo, 4, 1], f(4));
+
+f = foo.bind(foo, 1, 2, 3, 4);
+assertEquals(0, f.length);
+assertEquals([foo, 4, 1], f());
+
 // Test constructor calls.
 
 function bar(x, y, z) {
@@ -171,13 +206,91 @@
 
 
 // Test bind chains when used as a constructor.
-
 f = bar.bind(bar, 1).bind(bar, 2).bind(bar, 3);
 obj2 = new f();
 assertEquals(1, obj2.x);
 assertEquals(2, obj2.y);
 assertEquals(3, obj2.z);
 
-// Test instanceof obj2 is bar, not f.
+// Test obj2 is instanceof both bar and f.
 assertTrue(obj2 instanceof bar);
-assertFalse(obj2 instanceof f);
+assertTrue(obj2 instanceof f);
+
+// This-args are not relevant to instanceof.
+f = bar.bind(foo.prototype, 1).
+    bind(String.prototype, 2).
+    bind(Function.prototype, 3);
+var obj3 = new f();
+assertTrue(obj3 instanceof bar);
+assertTrue(obj3 instanceof f);
+assertFalse(obj3 instanceof foo);
+assertFalse(obj3 instanceof Function);
+assertFalse(obj3 instanceof String);
+
+// thisArg is converted to object.
+f = foo.bind(undefined);
+assertEquals([this, 0, undefined], f());
+
+f = foo.bind(null);
+assertEquals([this, 0, undefined], f());
+
+f = foo.bind(42);
+assertEquals([Object(42), 0, undefined], f());
+
+f = foo.bind("foo");
+assertEquals([Object("foo"), 0, undefined], f());
+
+f = foo.bind(true);
+assertEquals([Object(true), 0, undefined], f());
+
+// Strict functions don't convert thisArg.
+function soo(x, y, z) {
+  "use strict";
+  return [this, arguments.length, x];
+}
+
+var s = soo.bind(undefined);
+assertEquals([undefined, 0, undefined], s());
+
+s = soo.bind(null);
+assertEquals([null, 0, undefined], s());
+
+s = soo.bind(42);
+assertEquals([42, 0, undefined], s());
+
+s = soo.bind("foo");
+assertEquals(["foo", 0, undefined], s());
+
+s = soo.bind(true);
+assertEquals([true, 0, undefined], s());
+
+// Test that .arguments and .caller are poisoned according to the ES5 spec.
+
+// Check that property descriptors are correct (unconfigurable, unenumerable,
+// and both get and set is the ThrowTypeError function).
+var cdesc = Object.getOwnPropertyDescriptor(f, "caller");
+var adesc = Object.getOwnPropertyDescriptor(f, "arguments");
+
+assertFalse(cdesc.enumerable);
+assertFalse(cdesc.configurable);
+
+assertFalse(adesc.enumerable);
+assertFalse(adesc.configurable);
+
+assertSame(cdesc.get, cdesc.set);
+assertSame(cdesc.get, adesc.get);
+assertSame(cdesc.get, adesc.set);
+
+assertTrue(cdesc.get instanceof Function);
+assertEquals(0, cdesc.get.length);
+assertThrows(cdesc.get, TypeError);
+
+assertThrows(function() { return f.caller; }, TypeError);
+assertThrows(function() { f.caller = 42; }, TypeError);
+assertThrows(function() { return f.arguments; }, TypeError);
+assertThrows(function() { f.arguments = 42; }, TypeError);
+
+// Shouldn't throw. Accessing the functions caller must throw if
+// the caller is strict and the callee isn't. A bound function is built-in,
+// but not considered strict.
+(function foo() { return foo.caller; }).bind()();
diff --git a/test/mjsunit/fuzz-natives.js b/test/mjsunit/fuzz-natives.js
index ff6677e..c4d18d0 100644
--- a/test/mjsunit/fuzz-natives.js
+++ b/test/mjsunit/fuzz-natives.js
@@ -163,6 +163,9 @@
   "PromoteScheduledException": true,
   "DeleteHandleScopeExtensions": true,
 
+  // Vararg with minimum number > 0.
+  "Call": true,
+
   // Requires integer arguments to be non-negative.
   "Apply": true,
 
diff --git a/test/mjsunit/global-const-var-conflicts.js b/test/mjsunit/global-const-var-conflicts.js
index d38d0ee..2fca96f 100644
--- a/test/mjsunit/global-const-var-conflicts.js
+++ b/test/mjsunit/global-const-var-conflicts.js
@@ -26,7 +26,7 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // Check that dynamically introducing conflicting consts/vars
-// leads to exceptions.
+// is silently ignored (and does not lead to exceptions).
 
 var caught = 0;
 
@@ -46,12 +46,12 @@
 try { eval("const c"); } catch (e) { caught++; assertTrue(e instanceof TypeError); }
 assertTrue(typeof c == 'undefined');
 try { eval("const c = 1"); } catch (e) { caught++; assertTrue(e instanceof TypeError); }
-assertTrue(typeof c == 'undefined');
+assertEquals(1, c);
 
 eval("var d = 0");
 try { eval("const d"); } catch (e) { caught++; assertTrue(e instanceof TypeError); }
-assertEquals(0, d);
+assertEquals(undefined, d);
 try { eval("const d = 1"); } catch (e) { caught++; assertTrue(e instanceof TypeError); }
-assertEquals(0, d);
+assertEquals(1, d);
 
-assertEquals(8, caught);
+assertEquals(0, caught);
diff --git a/test/mjsunit/harmony/block-conflicts.js b/test/mjsunit/harmony/block-conflicts.js
index 8d3de6f..ee2d979 100644
--- a/test/mjsunit/harmony/block-conflicts.js
+++ b/test/mjsunit/harmony/block-conflicts.js
@@ -25,10 +25,13 @@
 // (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-block-scoping
+// Flags: --harmony-scoping
 
 // Test for conflicting variable bindings.
 
+// TODO(ES6): properly activate extended mode
+"use strict";
+
 function CheckException(e) {
   var string = e.toString();
   assertTrue(string.indexOf("has already been declared") >= 0 ||
@@ -80,6 +83,11 @@
                  "let x = function() {}",
                  "let x, y",
                  "let y, x",
+                 "const x = 0",
+                 "const x = undefined",
+                 "const x = function() {}",
+                 "const x = 2, y = 3",
+                 "const y = 4, x = 5",
                  ];
 var varbinds = [ "var x",
                  "var x = 0",
diff --git a/test/mjsunit/cyclic-error-to-string.js b/test/mjsunit/harmony/block-early-errors.js
similarity index 72%
copy from test/mjsunit/cyclic-error-to-string.js
copy to test/mjsunit/harmony/block-early-errors.js
index 2502b53..791f001 100644
--- a/test/mjsunit/cyclic-error-to-string.js
+++ b/test/mjsunit/harmony/block-early-errors.js
@@ -25,22 +25,31 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Test printing of cyclic errors which return the empty string for
-// compatibility with Safari and Firefox.
+// Flags: --harmony-scoping
 
-var e = new Error();
-assertEquals('Error', e + '');
+function CheckException(e) {
+  var string = e.toString();
+  assertInstanceof(e, SyntaxError);
+  assertTrue(string.indexOf("Illegal let") >= 0);
+}
 
-e = new Error();
-e.name = e;
-e.message = e;
-e.stack = e;
-e.arguments = e;
-assertEquals(': ', e + '');
+function Check(str) {
+  try {
+    eval("(function () { " + str + " })");
+    assertUnreachable();
+  } catch (e) {
+    CheckException(e);
+  }
+  try {
+    eval("(function () { { " + str + " } })");
+    assertUnreachable();
+  } catch (e) {
+    CheckException(e);
+  }
+}
 
-e = new Error();
-e.name = [ e ];
-e.message = [ e ];
-e.stack = [ e ];
-e.arguments = [ e ];
-assertEquals(': ', e + '');
+// Check for early syntax errors when using let
+// declarations outside of extended mode.
+Check("let x;");
+Check("let x = 1;");
+Check("let x, y;");
diff --git a/test/mjsunit/harmony/block-for.js b/test/mjsunit/harmony/block-for.js
new file mode 100644
index 0000000..e84f0d2
--- /dev/null
+++ b/test/mjsunit/harmony/block-for.js
@@ -0,0 +1,146 @@
+// 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: --harmony-scoping
+
+// TODO(ES6): properly activate extended mode
+"use strict";
+
+function props(x) {
+  var array = [];
+  for (let p in x) array.push(p);
+  return array.sort();
+}
+
+assertEquals(0, props({}).length);
+assertEquals(1, props({x:1}).length);
+assertEquals(2, props({x:1, y:2}).length);
+
+assertArrayEquals(["x"], props({x:1}));
+assertArrayEquals(["x", "y"], props({x:1, y:2}));
+assertArrayEquals(["x", "y", "zoom"], props({x:1, y:2, zoom:3}));
+
+assertEquals(0, props([]).length);
+assertEquals(1, props([1]).length);
+assertEquals(2, props([1,2]).length);
+
+assertArrayEquals(["0"], props([1]));
+assertArrayEquals(["0", "1"], props([1,2]));
+assertArrayEquals(["0", "1", "2"], props([1,2,3]));
+
+var o = {};
+var a = [];
+let i = "outer_i";
+let s = "outer_s";
+for (let i = 0x0020; i < 0x01ff; i+=2) {
+  let s = 'char:' + String.fromCharCode(i);
+  a.push(s);
+  o[s] = i;
+}
+assertArrayEquals(a, props(o));
+assertEquals(i, "outer_i");
+assertEquals(s, "outer_s");
+
+var a = [];
+assertEquals(0, props(a).length);
+a[Math.pow(2,30)-1] = 0;
+assertEquals(1, props(a).length);
+a[Math.pow(2,31)-1] = 0;
+assertEquals(2, props(a).length);
+a[1] = 0;
+assertEquals(3, props(a).length);
+
+var result = '';
+for (let p in {a : [0], b : 1}) { result += p; }
+assertEquals('ab', result);
+
+var result = '';
+for (let p in {a : {v:1}, b : 1}) { result += p; }
+assertEquals('ab', result);
+
+var result = '';
+for (let p in { get a() {}, b : 1}) { result += p; }
+assertEquals('ab', result);
+
+var result = '';
+for (let p in { get a() {}, set a(x) {}, b : 1}) { result += p; }
+assertEquals('ab', result);
+
+
+// Check that there is exactly one variable without initializer
+// in a for-in statement with let variables.
+// TODO(ES6): properly activate extended mode
+assertThrows("function foo() { 'use strict'; for (let in {}) { } }", SyntaxError);
+assertThrows("function foo() { 'use strict'; for (let x = 3 in {}) { } }", SyntaxError);
+assertThrows("function foo() { 'use strict'; for (let x, y in {}) { } }", SyntaxError);
+assertThrows("function foo() { 'use strict'; for (let x = 3, y in {}) { } }", SyntaxError);
+assertThrows("function foo() { 'use strict'; for (let x, y = 4 in {}) { } }", SyntaxError);
+assertThrows("function foo() { 'use strict'; for (let x = 3, y = 4 in {}) { } }", SyntaxError);
+
+
+// In a normal for statement the iteration variable is not
+// freshly allocated for each iteration.
+function closures1() {
+  let a = [];
+  for (let i = 0; i < 5; ++i) {
+    a.push(function () { return i; });
+  }
+  for (let j = 0; j < 5; ++j) {
+    assertEquals(5, a[j]());
+  }
+}
+closures1();
+
+
+function closures2() {
+  let a = [], b = [];
+  for (let i = 0, j = 10; i < 5; ++i, ++j) {
+    a.push(function () { return i; });
+    b.push(function () { return j; });
+  }
+  for (let k = 0; k < 5; ++k) {
+    assertEquals(5, a[k]());
+    assertEquals(15, b[k]());
+  }
+}
+closures2();
+
+
+// In a for-in statement the iteration variable is fresh
+// for earch iteration.
+function closures3(x) {
+  let a = [];
+  for (let p in x) {
+    a.push(function () { return p; });
+  }
+  let k = 0;
+  for (let q in x) {
+    assertEquals(q, a[k]());
+    ++k;
+  }
+}
+closures3({a : [0], b : 1, c : {v : 1}, get d() {}, set e(x) {}});
diff --git a/test/mjsunit/harmony/block-leave.js b/test/mjsunit/harmony/block-leave.js
index 73eaf29..a7f6b69 100644
--- a/test/mjsunit/harmony/block-leave.js
+++ b/test/mjsunit/harmony/block-leave.js
@@ -25,7 +25,10 @@
 // (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-block-scoping
+// Flags: --harmony-scoping
+
+// TODO(ES6): properly activate extended mode
+"use strict";
 
 // 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'
@@ -64,31 +67,30 @@
 } catch (e) {
   caught = true;
   assertEquals(25, e);
-  with ({y:19}) {
-    assertEquals(19, y);
+  (function () {
     try {
       // NOTE: This checks that the block scope containing xx has been
       // removed from the context chain.
-      xx;
+      eval('xx');
       assertTrue(false);  // should not reach here
     } catch (e2) {
       assertTrue(e2 instanceof ReferenceError);
     }
-  }
+  })();
 }
 assertTrue(caught);
 
 
-with ({x: 'outer'}) {
+(function(x) {
   label: {
     let x = 'inner';
     break label;
   }
-  assertEquals('outer', x);
-}
+  assertEquals('outer', eval('x'));
+})('outer');
 
 
-with ({x: 'outer'}) {
+(function(x) {
   label: {
     let x = 'middle';
     {
@@ -96,20 +98,20 @@
       break label;
     }
   }
-  assertEquals('outer', x);
-}
+  assertEquals('outer', eval('x'));
+})('outer');
 
 
-with ({x: 'outer'}) {
+(function(x) {
   for (var i = 0; i < 10; ++i) {
     let x = 'inner' + i;
     continue;
   }
-  assertEquals('outer', x);
-}
+  assertEquals('outer', eval('x'));
+})('outer');
 
 
-with ({x: 'outer'}) {
+(function(x) {
   label: for (var i = 0; i < 10; ++i) {
     let x = 'middle' + i;
     for (var j = 0; j < 10; ++j) {
@@ -117,21 +119,21 @@
       continue label;
     }
   }
-  assertEquals('outer', x);
-}
+  assertEquals('outer', eval('x'));
+})('outer');
 
 
-with ({x: 'outer'}) {
+(function(x) {
   try {
     let x = 'inner';
     throw 0;
   } catch (e) {
-    assertEquals('outer', x);
+    assertEquals('outer', eval('x'));
   }
-}
+})('outer');
 
 
-with ({x: 'outer'}) {
+(function(x) {
   try {
     let x = 'middle';
     {
@@ -139,27 +141,27 @@
       throw 0;
     }
   } catch (e) {
-    assertEquals('outer', x);
+    assertEquals('outer', eval('x'));
   }
-}
+})('outer');
 
 
 try {
-  with ({x: 'outer'}) {
+  (function(x) {
     try {
       let x = 'inner';
       throw 0;
     } finally {
-      assertEquals('outer', x);
+      assertEquals('outer', eval('x'));
     }
-  }
+  })('outer');
 } catch (e) {
   if (e instanceof MjsUnitAssertionError) throw e;
 }
 
 
 try {
-  with ({x: 'outer'}) {
+  (function(x) {
     try {
       let x = 'middle';
       {
@@ -167,9 +169,9 @@
         throw 0;
       }
     } finally {
-      assertEquals('outer', x);
+      assertEquals('outer', eval('x'));
     }
-  }
+  })('outer');
 } catch (e) {
   if (e instanceof MjsUnitAssertionError) throw e;
 }
@@ -179,47 +181,47 @@
 // from with.
 function f() {}
 
-with ({x: 'outer'}) {
+(function(x) {
   label: {
     let x = 'inner';
     break label;
   }
   f();  // The context could be restored from the stack after the call.
-  assertEquals('outer', x);
-}
+  assertEquals('outer', eval('x'));
+})('outer');
 
 
-with ({x: 'outer'}) {
+(function(x) {
   for (var i = 0; i < 10; ++i) {
     let x = 'inner';
     continue;
   }
   f();
-  assertEquals('outer', x);
-}
+  assertEquals('outer', eval('x'));
+})('outer');
 
 
-with ({x: 'outer'}) {
+(function(x) {
   try {
     let x = 'inner';
     throw 0;
   } catch (e) {
     f();
-    assertEquals('outer', x);
+    assertEquals('outer', eval('x'));
   }
-}
+})('outer');
 
 
 try {
-  with ({x: 'outer'}) {
+  (function(x) {
     try {
       let x = 'inner';
       throw 0;
     } finally {
       f();
-      assertEquals('outer', x);
+      assertEquals('outer', eval('x'));
     }
-  }
+  })('outer');
 } catch (e) {
   if (e instanceof MjsUnitAssertionError) throw e;
 }
diff --git a/test/mjsunit/harmony/block-let-crankshaft.js b/test/mjsunit/harmony/block-let-crankshaft.js
index c2fb96b..ba5bc0d 100644
--- a/test/mjsunit/harmony/block-let-crankshaft.js
+++ b/test/mjsunit/harmony/block-let-crankshaft.js
@@ -25,7 +25,10 @@
 // (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-block-scoping --allow-natives-syntax
+// Flags: --harmony-scoping --allow-natives-syntax
+
+// TODO(ES6): properly activate extended mode
+"use strict";
 
 // Test that temporal dead zone semantics for function and block scoped
 // ket bindings are handled by the optimizing compiler.
diff --git a/test/mjsunit/harmony/block-let-declaration.js b/test/mjsunit/harmony/block-let-declaration.js
index 49b6348..480e033 100644
--- a/test/mjsunit/harmony/block-let-declaration.js
+++ b/test/mjsunit/harmony/block-let-declaration.js
@@ -25,41 +25,113 @@
 // (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-block-scoping
+// Flags: --harmony-scoping
 
 // Test let declarations in various settings.
+// TODO(ES6): properly activate extended mode
+"use strict";
 
 // Global
 let x;
 let y = 2;
+const z = 4;
 
 // Block local
 {
   let y;
   let x = 3;
+  const z = 5;
 }
 
 assertEquals(undefined, x);
 assertEquals(2,y);
+assertEquals(4,z);
 
 if (true) {
   let y;
   assertEquals(undefined, y);
 }
 
+// Invalid declarations are early errors in harmony mode and thus should trigger
+// an exception in eval code during parsing, before even compiling or executing
+// the code. Thus the generated function is not called here.
 function TestLocalThrows(str, expect) {
-  assertThrows("(function(){" + str + "})()", expect);
+  assertThrows("(function(){ 'use strict'; " + str + "})", expect);
 }
 
 function TestLocalDoesNotThrow(str) {
-  assertDoesNotThrow("(function(){" + str + "})()");
+  assertDoesNotThrow("(function(){ 'use strict'; " + str + "})()");
 }
 
-// Unprotected statement
+// Test let declarations in statement positions.
 TestLocalThrows("if (true) let x;", SyntaxError);
+TestLocalThrows("if (true) {} else let x;", SyntaxError);
 TestLocalThrows("do let x; while (false)", SyntaxError);
 TestLocalThrows("while (false) let x;", SyntaxError);
+TestLocalThrows("label: let x;", SyntaxError);
+TestLocalThrows("for (;false;) let x;", SyntaxError);
+TestLocalThrows("switch (true) { case true: let x; }", SyntaxError);
+TestLocalThrows("switch (true) { default: let x; }", SyntaxError);
 
+// Test const declarations with initialisers in statement positions.
+TestLocalThrows("if (true) const x = 1;", SyntaxError);
+TestLocalThrows("if (true) {} else const x = 1;", SyntaxError);
+TestLocalThrows("do const x = 1; while (false)", SyntaxError);
+TestLocalThrows("while (false) const x = 1;", SyntaxError);
+TestLocalThrows("label: const x = 1;", SyntaxError);
+TestLocalThrows("for (;false;) const x = 1;", SyntaxError);
+TestLocalThrows("switch (true) { case true: const x = 1; }", SyntaxError);
+TestLocalThrows("switch (true) { default: const x = 1; }", SyntaxError);
+
+// Test const declarations without initialisers.
+TestLocalThrows("const x;", SyntaxError);
+TestLocalThrows("const x = 1, y;", SyntaxError);
+TestLocalThrows("const x, y = 1;", SyntaxError);
+
+// Test const declarations without initialisers in statement positions.
+TestLocalThrows("if (true) const x;", SyntaxError);
+TestLocalThrows("if (true) {} else const x;", SyntaxError);
+TestLocalThrows("do const x; while (false)", SyntaxError);
+TestLocalThrows("while (false) const x;", SyntaxError);
+TestLocalThrows("label: const x;", SyntaxError);
+TestLocalThrows("for (;false;) const x;", SyntaxError);
+TestLocalThrows("switch (true) { case true: const x; }", SyntaxError);
+TestLocalThrows("switch (true) { default: const x; }", SyntaxError);
+
+// Test var declarations in statement positions.
 TestLocalDoesNotThrow("if (true) var x;");
+TestLocalDoesNotThrow("if (true) {} else var x;");
 TestLocalDoesNotThrow("do var x; while (false)");
 TestLocalDoesNotThrow("while (false) var x;");
+TestLocalDoesNotThrow("label: var x;");
+TestLocalDoesNotThrow("for (;false;) var x;");
+TestLocalDoesNotThrow("switch (true) { case true: var x; }");
+TestLocalDoesNotThrow("switch (true) { default: var x; }");
+
+// Test function declarations in source element and
+// non-strict statement positions.
+function f() {
+  // Non-strict source element positions.
+  function g0() {
+    "use strict";
+    // Strict source element positions.
+    function h() { }
+    {
+      function h1() { }
+    }
+  }
+  {
+    function g1() { }
+  }
+}
+f();
+
+// Test function declarations in statement position in strict mode.
+TestLocalThrows("function f() { if (true) function g() {}", SyntaxError);
+TestLocalThrows("function f() { if (true) {} else function g() {}", SyntaxError);
+TestLocalThrows("function f() { do function g() {} while (false)", SyntaxError);
+TestLocalThrows("function f() { while (false) function g() {}", SyntaxError);
+TestLocalThrows("function f() { label: function g() {}", SyntaxError);
+TestLocalThrows("function f() { for (;false;) function g() {}", SyntaxError);
+TestLocalThrows("function f() { switch (true) { case true: function g() {} }", SyntaxError);
+TestLocalThrows("function f() { switch (true) { default: function g() {} }", SyntaxError);
diff --git a/test/mjsunit/harmony/block-let-semantics.js b/test/mjsunit/harmony/block-let-semantics.js
index 198c3b4..d14e7cd 100644
--- a/test/mjsunit/harmony/block-let-semantics.js
+++ b/test/mjsunit/harmony/block-let-semantics.js
@@ -25,7 +25,10 @@
 // (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-block-scoping
+// Flags: --harmony-scoping
+
+// TODO(ES6): properly activate extended mode
+"use strict";
 
 // Test temporal dead zone semantics of let bound variables in
 // function and block scopes.
@@ -61,6 +64,7 @@
 TestAll('let x = x += 1');
 TestAll('let x = x++');
 TestAll('let x = ++x');
+TestAll('const x = x + 1');
 
 // Use before initialization in prior statement.
 TestAll('x + 1; let x;');
@@ -68,25 +72,36 @@
 TestAll('x += 1; let x;');
 TestAll('++x; let x;');
 TestAll('x++; let x;');
+TestAll('let y = x; const x = 1;');
 
 TestAll('f(); let x; function f() { return x + 1; }');
 TestAll('f(); let x; function f() { x = 1; }');
 TestAll('f(); let x; function f() { x += 1; }');
 TestAll('f(); let x; function f() { ++x; }');
 TestAll('f(); let x; function f() { x++; }');
+TestAll('f(); const x = 1; function f() { return x; }');
 
 TestAll('f()(); let x; function f() { return function() { return x + 1; } }');
 TestAll('f()(); let x; function f() { return function() { x = 1; } }');
 TestAll('f()(); let x; function f() { return function() { x += 1; } }');
 TestAll('f()(); let x; function f() { return function() { ++x; } }');
 TestAll('f()(); let x; function f() { return function() { x++; } }');
+TestAll('f()(); const x = 1; function f() { return function() { return x; } }');
 
-// Use in before initialization with a dynamic lookup.
+// Use before initialization with a dynamic lookup.
 TestAll('eval("x + 1;"); let x;');
 TestAll('eval("x = 1;"); let x;');
 TestAll('eval("x += 1;"); let x;');
 TestAll('eval("++x;"); let x;');
 TestAll('eval("x++;"); let x;');
+TestAll('eval("x"); const x = 1;');
+
+// Use before initialization with check for eval-shadowed bindings.
+TestAll('function f() { eval("var y = 2;"); x + 1; }; f(); let x;');
+TestAll('function f() { eval("var y = 2;"); x = 1; }; f(); let x;');
+TestAll('function f() { eval("var y = 2;"); x += 1; }; f(); let x;');
+TestAll('function f() { eval("var y = 2;"); ++x; }; f(); let x;');
+TestAll('function f() { eval("var y = 2;"); x++; }; f(); let x;');
 
 // Test that variables introduced by function declarations are created and
 // initialized upon entering a function / block scope.
@@ -115,7 +130,7 @@
 
 // Test that a function declaration sees the scope it resides in.
 function f2() {
-  let m, n;
+  let m, n, o, p;
   {
     m = g;
     function g() {
@@ -132,7 +147,44 @@
     function h() {
       return b + c;
     }
-    let b = 3;
+    let c = 3;
   }
   assertEquals(5, n());
+
+  {
+    o = i;
+    function i() {
+      return d;
+    }
+    let d = 4;
+  }
+  assertEquals(4, o());
+
+  try {
+    throw 5;
+  } catch(e) {
+    p = j;
+    function j() {
+      return e + f;
+    }
+    let f = 6;
+  }
+  assertEquals(11, p());
 }
+f2();
+
+// Test that resolution of let bound variables works with scopes that call eval.
+function outer() {
+  function middle() {
+    function inner() {
+      return x;
+    }
+    eval("1 + 1");
+    return x + inner();
+  }
+
+  let x = 1;
+  return middle();
+}
+
+assertEquals(2, outer());
diff --git a/test/mjsunit/harmony/block-scoping.js b/test/mjsunit/harmony/block-scoping.js
index 266e380..31194d9 100644
--- a/test/mjsunit/harmony/block-scoping.js
+++ b/test/mjsunit/harmony/block-scoping.js
@@ -25,9 +25,12 @@
 // (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-block-scoping
+// Flags: --allow-natives-syntax --harmony-scoping
 // Test functionality of block scopes.
 
+// TODO(ES6): properly activate extended mode
+"use strict";
+
 // Hoisting of var declarations.
 function f1() {
   {
@@ -44,12 +47,16 @@
 function f2(one) {
   var x = one + 1;
   let y = one + 2;
+  const u = one + 4;
   {
     let z = one + 3;
+    const v = one + 5;
     assertEquals(1, eval('one'));
     assertEquals(2, eval('x'));
     assertEquals(3, eval('y'));
     assertEquals(4, eval('z'));
+    assertEquals(5, eval('u'));
+    assertEquals(6, eval('v'));
   }
 }
 f2(1);
@@ -59,12 +66,17 @@
 function f3(one) {
   var x = one + 1;
   let y = one + 2;
+  const u = one + 4;
   {
     let z = one + 3;
+    const v = one + 5;
     assertEquals(1, one);
     assertEquals(2, x);
     assertEquals(3, y);
     assertEquals(4, z);
+    assertEquals(5, u);
+    assertEquals(6, v);
+
   }
 }
 f3(1);
@@ -74,13 +86,17 @@
 function f4(one) {
   var x = one + 1;
   let y = one + 2;
+  const u = one + 4;
   {
     let z = one + 3;
+    const v = one + 5;
     function f() {
       assertEquals(1, eval('one'));
       assertEquals(2, eval('x'));
       assertEquals(3, eval('y'));
       assertEquals(4, eval('z'));
+      assertEquals(5, eval('u'));
+      assertEquals(6, eval('v'));
     };
   }
 }
@@ -91,13 +107,17 @@
 function f5(one) {
   var x = one + 1;
   let y = one + 2;
+  const u = one + 4;
   {
     let z = one + 3;
+    const v = one + 5;
     function f() {
       assertEquals(1, one);
       assertEquals(2, x);
       assertEquals(3, y);
       assertEquals(4, z);
+      assertEquals(5, u);
+      assertEquals(6, v);
     };
   }
 }
@@ -107,8 +127,10 @@
 // Return from block.
 function f6() {
   let x = 1;
+  const u = 3;
   {
     let y = 2;
+    const v = 4;
     return x + y;
   }
 }
@@ -120,13 +142,26 @@
   let b = 1;
   var c = 1;
   var d = 1;
-  { // let variables shadowing argument, let and var variables
+  const e = 1;
+  { // let variables shadowing argument, let, const and var variables
     let a = 2;
     let b = 2;
     let c = 2;
+    let e = 2;
     assertEquals(2,a);
     assertEquals(2,b);
     assertEquals(2,c);
+    assertEquals(2,e);
+  }
+  { // const variables shadowing argument, let, const and var variables
+    const a = 2;
+    const b = 2;
+    const c = 2;
+    const e = 2;
+    assertEquals(2,a);
+    assertEquals(2,b);
+    assertEquals(2,c);
+    assertEquals(2,e);
   }
   try {
     throw 'stuff1';
@@ -156,6 +191,12 @@
   } catch (c) {
     // catch variable shadowing var variable
     assertEquals('stuff3',c);
+    {
+      // const variable shadowing catch variable
+      const c = 3;
+      assertEquals(3,c);
+    }
+    assertEquals('stuff3',c);
     try {
       throw 'stuff4';
     } catch(c) {
@@ -178,14 +219,16 @@
     c = 2;
   }
   assertEquals(1,c);
-  (function(a,b,c) {
-    // arguments shadowing argument, let and var variable
+  (function(a,b,c,e) {
+    // arguments shadowing argument, let, const and var variable
     a = 2;
     b = 2;
     c = 2;
+    e = 2;
     assertEquals(2,a);
     assertEquals(2,b);
     assertEquals(2,c);
+    assertEquals(2,e);
     // var variable shadowing var variable
     var d = 2;
   })(1,1);
@@ -193,24 +236,30 @@
   assertEquals(1,b);
   assertEquals(1,c);
   assertEquals(1,d);
+  assertEquals(1,e);
 }
 f7(1);
 
 
-// Ensure let variables are block local and var variables function local.
+// Ensure let and const variables are block local
+// and var variables function local.
 function f8() {
   var let_accessors = [];
   var var_accessors = [];
+  var const_accessors = [];
   for (var i = 0; i < 10; i++) {
     let x = i;
     var y = i;
+    const z = i;
     let_accessors[i] = function() { return x; }
     var_accessors[i] = function() { return y; }
+    const_accessors[i] = function() { return z; }
   }
   for (var j = 0; j < 10; j++) {
     y = j + 10;
     assertEquals(j, let_accessors[j]());
     assertEquals(y, var_accessors[j]());
+    assertEquals(j, const_accessors[j]());
   }
 }
 f8();
diff --git a/test/mjsunit/harmony/collections.js b/test/mjsunit/harmony/collections.js
new file mode 100644
index 0000000..4b435c1
--- /dev/null
+++ b/test/mjsunit/harmony/collections.js
@@ -0,0 +1,280 @@
+// 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: --harmony-collections --expose-gc
+
+
+// Test valid getter and setter calls on Sets.
+function TestValidSetCalls(m) {
+  assertDoesNotThrow(function () { m.add(new Object) });
+  assertDoesNotThrow(function () { m.has(new Object) });
+  assertDoesNotThrow(function () { m.delete(new Object) });
+}
+TestValidSetCalls(new Set);
+
+
+// Test valid getter and setter calls on Maps and WeakMaps
+function TestValidMapCalls(m) {
+  assertDoesNotThrow(function () { m.get(new Object) });
+  assertDoesNotThrow(function () { m.set(new Object) });
+  assertDoesNotThrow(function () { m.has(new Object) });
+  assertDoesNotThrow(function () { m.delete(new Object) });
+}
+TestValidMapCalls(new Map);
+TestValidMapCalls(new WeakMap);
+
+
+// Test invalid getter and setter calls for WeakMap only
+function TestInvalidCalls(m) {
+  assertThrows(function () { m.get(undefined) }, TypeError);
+  assertThrows(function () { m.set(undefined, 0) }, TypeError);
+  assertThrows(function () { m.get(null) }, TypeError);
+  assertThrows(function () { m.set(null, 0) }, TypeError);
+  assertThrows(function () { m.get(0) }, TypeError);
+  assertThrows(function () { m.set(0, 0) }, TypeError);
+  assertThrows(function () { m.get('a-key') }, TypeError);
+  assertThrows(function () { m.set('a-key', 0) }, TypeError);
+}
+TestInvalidCalls(new WeakMap);
+
+
+// Test expected behavior for Sets
+function TestSet(set, key) {
+  assertFalse(set.has(key));
+  set.add(key);
+  assertTrue(set.has(key));
+  set.delete(key);
+  assertFalse(set.has(key));
+}
+function TestSetBehavior(set) {
+  for (var i = 0; i < 20; i++) {
+    TestSet(set, new Object);
+    TestSet(set, i);
+    TestSet(set, i / 100);
+    TestSet(set, 'key-' + i);
+  }
+  var keys = [ +0, -0, +Infinity, -Infinity, true, false, null, undefined ];
+  for (var i = 0; i < keys.length; i++) {
+    TestSet(set, keys[i]);
+  }
+}
+TestSetBehavior(new Set);
+
+
+// Test expected mapping behavior for Maps and WeakMaps
+function TestMapping(map, key, value) {
+  map.set(key, value);
+  assertSame(value, map.get(key));
+}
+function TestMapBehavior1(m) {
+  TestMapping(m, new Object, 23);
+  TestMapping(m, new Object, 'the-value');
+  TestMapping(m, new Object, new Object);
+}
+TestMapBehavior1(new Map);
+TestMapBehavior1(new WeakMap);
+
+
+// Test expected mapping behavior for Maps only
+function TestMapBehavior2(m) {
+  for (var i = 0; i < 20; i++) {
+    TestMapping(m, i, new Object);
+    TestMapping(m, i / 10, new Object);
+    TestMapping(m, 'key-' + i, new Object);
+  }
+  var keys = [ +0, -0, +Infinity, -Infinity, true, false, null, undefined ];
+  for (var i = 0; i < keys.length; i++) {
+    TestMapping(m, keys[i], new Object);
+  }
+}
+TestMapBehavior2(new Map);
+
+
+// Test expected querying behavior of Maps and WeakMaps
+function TestQuery(m) {
+  var key = new Object;
+  TestMapping(m, key, 'to-be-present');
+  assertTrue(m.has(key));
+  assertFalse(m.has(new Object));
+  TestMapping(m, key, undefined);
+  assertFalse(m.has(key));
+  assertFalse(m.has(new Object));
+}
+TestQuery(new Map);
+TestQuery(new WeakMap);
+
+
+// Test expected deletion behavior of Maps and WeakMaps
+function TestDelete(m) {
+  var key = new Object;
+  TestMapping(m, key, 'to-be-deleted');
+  assertTrue(m.delete(key));
+  assertFalse(m.delete(key));
+  assertFalse(m.delete(new Object));
+  assertSame(m.get(key), undefined);
+}
+TestDelete(new Map);
+TestDelete(new WeakMap);
+
+
+// Test GC of Maps and WeakMaps with entry
+function TestGC1(m) {
+  var key = new Object;
+  m.set(key, 'not-collected');
+  gc();
+  assertSame('not-collected', m.get(key));
+}
+TestGC1(new Map);
+TestGC1(new WeakMap);
+
+
+// Test GC of Maps and WeakMaps with chained entries
+function TestGC2(m) {
+  var head = new Object;
+  for (key = head, i = 0; i < 10; i++, key = m.get(key)) {
+    m.set(key, new Object);
+  }
+  gc();
+  var count = 0;
+  for (key = head; key != undefined; key = m.get(key)) {
+    count++;
+  }
+  assertEquals(11, count);
+}
+TestGC2(new Map);
+TestGC2(new WeakMap);
+
+
+// Test property attribute [[Enumerable]]
+function TestEnumerable(func) {
+  function props(x) {
+    var array = [];
+    for (var p in x) array.push(p);
+    return array.sort();
+  }
+  assertArrayEquals([], props(func));
+  assertArrayEquals([], props(func.prototype));
+  assertArrayEquals([], props(new func()));
+}
+TestEnumerable(Set);
+TestEnumerable(Map);
+TestEnumerable(WeakMap);
+
+
+// Test arbitrary properties on Maps and WeakMaps
+function TestArbitrary(m) {
+  function TestProperty(map, property, value) {
+    map[property] = value;
+    assertEquals(value, map[property]);
+  }
+  for (var i = 0; i < 20; i++) {
+    TestProperty(m, i, 'val' + i);
+    TestProperty(m, 'foo' + i, 'bar' + i);
+  }
+  TestMapping(m, new Object, 'foobar');
+}
+TestArbitrary(new Map);
+TestArbitrary(new WeakMap);
+
+
+// Test direct constructor call
+assertTrue(Set() instanceof Set);
+assertTrue(Map() instanceof Map);
+assertTrue(WeakMap() instanceof WeakMap);
+
+
+// Test whether NaN values as keys are treated correctly.
+var s = new Set;
+assertFalse(s.has(NaN));
+assertFalse(s.has(NaN + 1));
+assertFalse(s.has(23));
+s.add(NaN);
+assertTrue(s.has(NaN));
+assertTrue(s.has(NaN + 1));
+assertFalse(s.has(23));
+var m = new Map;
+assertFalse(m.has(NaN));
+assertFalse(m.has(NaN + 1));
+assertFalse(m.has(23));
+m.set(NaN, 'a-value');
+assertTrue(m.has(NaN));
+assertTrue(m.has(NaN + 1));
+assertFalse(m.has(23));
+
+
+// Test some common JavaScript idioms for Sets
+var s = new Set;
+assertTrue(s instanceof Set);
+assertTrue(Set.prototype.add instanceof Function)
+assertTrue(Set.prototype.has instanceof Function)
+assertTrue(Set.prototype.delete instanceof Function)
+
+
+// Test some common JavaScript idioms for Maps
+var m = new Map;
+assertTrue(m instanceof Map);
+assertTrue(Map.prototype.set instanceof Function)
+assertTrue(Map.prototype.get instanceof Function)
+assertTrue(Map.prototype.has instanceof Function)
+assertTrue(Map.prototype.delete instanceof Function)
+
+
+// Test some common JavaScript idioms for WeakMaps
+var m = new WeakMap;
+assertTrue(m instanceof WeakMap);
+assertTrue(WeakMap.prototype.set instanceof Function)
+assertTrue(WeakMap.prototype.get instanceof Function)
+assertTrue(WeakMap.prototype.has instanceof Function)
+assertTrue(WeakMap.prototype.delete instanceof Function)
+
+
+// Regression test for WeakMap prototype.
+assertTrue(WeakMap.prototype.constructor === WeakMap)
+assertTrue(Object.getPrototypeOf(WeakMap.prototype) === Object.prototype)
+
+
+// Regression test for issue 1617: The prototype of the WeakMap constructor
+// needs to be unique (i.e. different from the one of the Object constructor).
+assertFalse(WeakMap.prototype === Object.prototype);
+var o = Object.create({});
+assertFalse("get" in o);
+assertFalse("set" in o);
+assertEquals(undefined, o.get);
+assertEquals(undefined, o.set);
+var o = Object.create({}, { myValue: {
+  value: 10,
+  enumerable: false,
+  configurable: true,
+  writable: true
+}});
+assertEquals(10, o.myValue);
+
+
+// Stress Test
+// There is a proposed stress-test available at the es-discuss mailing list
+// which cannot be reasonably automated.  Check it out by hand if you like:
+// https://mail.mozilla.org/pipermail/es-discuss/2011-May/014096.html
\ No newline at end of file
diff --git a/test/mjsunit/harmony/debug-blockscopes.js b/test/mjsunit/harmony/debug-blockscopes.js
index 0230e84..10aac2d 100644
--- a/test/mjsunit/harmony/debug-blockscopes.js
+++ b/test/mjsunit/harmony/debug-blockscopes.js
@@ -25,13 +25,15 @@
 // (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: --expose-debug-as debug --harmony-block-scoping
+// Flags: --expose-debug-as debug --harmony-scoping
 // The functions used for testing backtraces. They are at the top to make the
 // testing of source line/column easier.
 
+// TODO(ES6): properly activate extended mode
+"use strict";
 
 // Get the Debug object exposed from the debug context global object.
-Debug = debug.Debug;
+var Debug = debug.Debug;
 
 var test_name;
 var listener_delegate;
@@ -76,6 +78,7 @@
   end_test_count++;
 }
 
+var global_object = this;
 
 // Check that the scope chain contains the expected types of scopes.
 function CheckScopeChain(scopes, exec_state) {
@@ -89,7 +92,7 @@
     if (scopes[i] == debug.ScopeType.Global) {
       // Objects don't have same class (one is "global", other is "Object",
       // so just check the properties directly.
-      assertPropertiesEqual(this, scope.scopeObject().value());
+      assertPropertiesEqual(global_object, scope.scopeObject().value());
     }
   }
 
@@ -329,114 +332,6 @@
 EndTest();
 
 
-// Single empty with block.
-BeginTest("With block 1");
-
-function with_block_1() {
-  with({}) {
-    debugger;
-  }
-}
-
-listener_delegate = function(exec_state) {
-  CheckScopeChain([debug.ScopeType.With,
-                   debug.ScopeType.Local,
-                   debug.ScopeType.Global], exec_state);
-  CheckScopeContent({}, 0, exec_state);
-  CheckScopeContent({}, 1, exec_state);
-};
-with_block_1();
-EndTest();
-
-
-// Nested empty with blocks.
-BeginTest("With block 2");
-
-function with_block_2() {
-  with({}) {
-    with({}) {
-      debugger;
-    }
-  }
-}
-
-listener_delegate = function(exec_state) {
-  CheckScopeChain([debug.ScopeType.With,
-                   debug.ScopeType.With,
-                   debug.ScopeType.Local,
-                   debug.ScopeType.Global], exec_state);
-  CheckScopeContent({}, 0, exec_state);
-  CheckScopeContent({}, 1, exec_state);
-  CheckScopeContent({}, 2, exec_state);
-};
-with_block_2();
-EndTest();
-
-
-// With block using an in-place object literal.
-BeginTest("With block 3");
-
-function with_block_3() {
-  with({a:1,b:2}) {
-    debugger;
-  }
-}
-
-listener_delegate = function(exec_state) {
-  CheckScopeChain([debug.ScopeType.With,
-                   debug.ScopeType.Local,
-                   debug.ScopeType.Global], exec_state);
-  CheckScopeContent({a:1,b:2}, 0, exec_state);
-};
-with_block_3();
-EndTest();
-
-
-// Nested with blocks using in-place object literals.
-BeginTest("With block 4");
-
-function with_block_4() {
-  with({a:1,b:2}) {
-    with({a:2,b:1}) {
-      debugger;
-    }
-  }
-}
-
-listener_delegate = function(exec_state) {
-  CheckScopeChain([debug.ScopeType.With,
-                   debug.ScopeType.With,
-                   debug.ScopeType.Local,
-                   debug.ScopeType.Global], exec_state);
-  CheckScopeContent({a:2,b:1}, 0, exec_state);
-  CheckScopeContent({a:1,b:2}, 1, exec_state);
-};
-with_block_4();
-EndTest();
-
-
-// With block and a block local variable.
-BeginTest("With block 5");
-
-function with_block_5() {
-  with({a:1}) {
-    let a = 2;
-    debugger;
-  }
-}
-
-listener_delegate = function(exec_state) {
-  CheckScopeChain([debug.ScopeType.Block,
-                   debug.ScopeType.With,
-                   debug.ScopeType.Local,
-                   debug.ScopeType.Global], exec_state);
-  CheckScopeContent({a:2}, 0, exec_state);
-  CheckScopeContent({a:1}, 1, exec_state);
-};
-with_block_5();
-EndTest();
-
-
 // Simple closure formed by returning an inner function referering to an outer
 // block local variable and an outer function's parameter.
 BeginTest("Closure 1");
@@ -464,3 +359,112 @@
 };
 closure_1(1)();
 EndTest();
+
+
+// Simple for-in loop over the keys of an object.
+BeginTest("For loop 1");
+
+function for_loop_1() {
+  for (let x in {y:undefined}) {
+    debugger;
+  }
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Block,
+                   debug.ScopeType.Local,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({x:'y'}, 0, exec_state);
+  // The function scope contains a temporary iteration variable.
+  CheckScopeContent({x:'y'}, 1, exec_state);
+};
+for_loop_1();
+EndTest();
+
+
+// For-in loop over the keys of an object with a block scoped let variable
+// shadowing the iteration variable.
+BeginTest("For loop 2");
+
+function for_loop_2() {
+  for (let x in {y:undefined}) {
+    let x = 3;
+    debugger;
+  }
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Block,
+                   debug.ScopeType.Block,
+                   debug.ScopeType.Local,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({x:3}, 0, exec_state);
+  CheckScopeContent({x:'y'}, 1, exec_state);
+  // The function scope contains a temporary iteration variable.
+  CheckScopeContent({x:'y'}, 2, exec_state);
+};
+for_loop_2();
+EndTest();
+
+
+// Simple for loop.
+BeginTest("For loop 3");
+
+function for_loop_3() {
+  for (let x = 3; x < 4; ++x) {
+    debugger;
+  }
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Block,
+                   debug.ScopeType.Local,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({x:3}, 0, exec_state);
+  CheckScopeContent({}, 1, exec_state);
+};
+for_loop_3();
+EndTest();
+
+
+// For loop with a block scoped let variable shadowing the iteration variable.
+BeginTest("For loop 4");
+
+function for_loop_4() {
+  for (let x = 3; x < 4; ++x) {
+    let x = 5;
+    debugger;
+  }
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Block,
+                   debug.ScopeType.Block,
+                   debug.ScopeType.Local,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({x:5}, 0, exec_state);
+  CheckScopeContent({x:3}, 1, exec_state);
+  CheckScopeContent({}, 2, exec_state);
+};
+for_loop_4();
+EndTest();
+
+
+// For loop with two variable declarations.
+BeginTest("For loop 5");
+
+function for_loop_5() {
+  for (let x = 3, y = 5; x < 4; ++x) {
+    debugger;
+  }
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Block,
+                   debug.ScopeType.Local,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({x:3,y:5}, 0, exec_state);
+  CheckScopeContent({}, 1, exec_state);
+};
+for_loop_5();
+EndTest();
diff --git a/test/mjsunit/harmony/debug-evaluate-blockscopes.js b/test/mjsunit/harmony/debug-evaluate-blockscopes.js
index 549960a..d6ce8b2 100644
--- a/test/mjsunit/harmony/debug-evaluate-blockscopes.js
+++ b/test/mjsunit/harmony/debug-evaluate-blockscopes.js
@@ -25,11 +25,17 @@
 // (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: --expose-debug-as debug --harmony-block-scoping
+// Flags: --expose-debug-as debug --harmony-scoping
 
 // Test debug evaluation for functions without local context, but with
 // nested catch contexts.
 
+// TODO(ES6): properly activate extended mode
+"use strict";
+
+var x;
+var result;
+
 function f() {
   {                   // Line 1.
     let i = 1;        // Line 2.
@@ -42,7 +48,7 @@
 };
 
 // Get the Debug object exposed from the debug context global object.
-Debug = debug.Debug
+var Debug = debug.Debug
 // Set breakpoint on line 6.
 var bp = Debug.setBreakPoint(f, 6);
 
diff --git a/test/mjsunit/harmony/proxies-example-membrane.js b/test/mjsunit/harmony/proxies-example-membrane.js
new file mode 100644
index 0000000..c6e7f9f
--- /dev/null
+++ b/test/mjsunit/harmony/proxies-example-membrane.js
@@ -0,0 +1,512 @@
+// 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: --harmony
+
+
+// A simple no-op handler. Adapted from:
+// http://wiki.ecmascript.org/doku.php?id=harmony:proxies#examplea_no-op_forwarding_proxy
+
+function createHandler(obj) {
+  return {
+    getOwnPropertyDescriptor: function(name) {
+      var desc = Object.getOwnPropertyDescriptor(obj, name);
+      if (desc !== undefined) desc.configurable = true;
+      return desc;
+    },
+    getPropertyDescriptor: function(name) {
+      var desc = Object.getOwnPropertyDescriptor(obj, name);
+      //var desc = Object.getPropertyDescriptor(obj, name);  // not in ES5
+      if (desc !== undefined) desc.configurable = true;
+      return desc;
+    },
+    getOwnPropertyNames: function() {
+      return Object.getOwnPropertyNames(obj);
+    },
+    getPropertyNames: function() {
+      return Object.getOwnPropertyNames(obj);
+      //return Object.getPropertyNames(obj);  // not in ES5
+    },
+    defineProperty: function(name, desc) {
+      Object.defineProperty(obj, name, desc);
+    },
+    delete: function(name) {
+      return delete obj[name];
+    },
+    fix: function() {
+      if (Object.isFrozen(obj)) {
+        var result = {};
+        Object.getOwnPropertyNames(obj).forEach(function(name) {
+          result[name] = Object.getOwnPropertyDescriptor(obj, name);
+        });
+        return result;
+      }
+      // As long as obj is not frozen, the proxy won't allow itself to be fixed
+      return undefined; // will cause a TypeError to be thrown
+    },
+    has: function(name) { return name in obj; },
+    hasOwn: function(name) { return ({}).hasOwnProperty.call(obj, name); },
+    get: function(receiver, name) { return obj[name]; },
+    set: function(receiver, name, val) {
+      obj[name] = val;  // bad behavior when set fails in non-strict mode
+      return true;
+    },
+    enumerate: function() {
+      var result = [];
+      for (var name in obj) { result.push(name); };
+      return result;
+    },
+    keys: function() { return Object.keys(obj); }
+  };
+}
+
+
+
+// Auxiliary definitions enabling tracking of object identity in output.
+
+var objectMap = new WeakMap;
+var objectCounter = 0;
+
+function registerObject(x, s) {
+  if (x === Object(x) && !objectMap.has(x))
+    objectMap.set(x, ++objectCounter + (s == undefined ? "" : ":" + s));
+}
+
+registerObject(this, "global");
+registerObject(Object.prototype, "Object.prototype");
+
+function str(x) {
+  if (x === Object(x)) return "[" + typeof x + " " + objectMap.get(x) + "]";
+  if (typeof x == "string") return "\"" + x + "\"";
+  return "" + x;
+}
+
+
+
+// A simple membrane. Adapted from:
+// http://wiki.ecmascript.org/doku.php?id=harmony:proxies#a_simple_membrane
+
+function createSimpleMembrane(target) {
+  var enabled = true;
+
+  function wrap(obj) {
+    registerObject(obj);
+    print("wrap enter", str(obj));
+    try {
+      var x = wrap2(obj);
+      registerObject(x, "wrapped");
+      print("wrap exit", str(obj), "as", str(x));
+      return x;
+    } catch(e) {
+      print("wrap exception", str(e));
+      throw e;
+    }
+  }
+
+  function wrap2(obj) {
+    if (obj !== Object(obj)) {
+      return obj;
+    }
+
+    function wrapCall(fun, that, args) {
+      registerObject(that);
+      print("wrapCall enter", fun, str(that));
+      try {
+        var x = wrapCall2(fun, that, args);
+        print("wrapCall exit", fun, str(that), "returning", str(x));
+        return x;
+      } catch(e) {
+        print("wrapCall exception", fun, str(that), str(e));
+        throw e;
+      }
+    }
+
+    function wrapCall2(fun, that, args) {
+      if (!enabled) { throw new Error("disabled"); }
+      try {
+        return wrap(fun.apply(that, Array.prototype.map.call(args, wrap)));
+      } catch (e) {
+        throw wrap(e);
+      }
+    }
+
+    var baseHandler = createHandler(obj);
+    var handler = Proxy.create(Object.freeze({
+      get: function(receiver, name) {
+        return function() {
+          var arg = (name === "get" || name == "set") ? arguments[1] : "";
+          print("handler enter", name, arg);
+          var x = wrapCall(baseHandler[name], baseHandler, arguments);
+          print("handler exit", name, arg, "returning", str(x));
+          return x;
+        }
+      }
+    }));
+    registerObject(baseHandler, "basehandler");
+    registerObject(handler, "handler");
+
+    if (typeof obj === "function") {
+      function callTrap() {
+        print("call trap enter", str(obj), str(this));
+        var x = wrapCall(obj, wrap(this), arguments);
+        print("call trap exit", str(obj), str(this), "returning", str(x));
+        return x;
+      }
+      function constructTrap() {
+        if (!enabled) { throw new Error("disabled"); }
+        try {
+          function forward(args) { return obj.apply(this, args) }
+          return wrap(new forward(Array.prototype.map.call(arguments, wrap)));
+        } catch (e) {
+          throw wrap(e);
+        }
+      }
+      return Proxy.createFunction(handler, callTrap, constructTrap);
+    } else {
+      var prototype = wrap(Object.getPrototypeOf(obj));
+      return Proxy.create(handler, prototype);
+    }
+  }
+
+  var gate = Object.freeze({
+    enable: function() { enabled = true; },
+    disable: function() { enabled = false; }
+  });
+
+  return Object.freeze({
+    wrapper: wrap(target),
+    gate: gate
+  });
+}
+
+
+var o = {
+  a: 6,
+  b: {bb: 8},
+  f: function(x) { return x },
+  g: function(x) { return x.a },
+  h: function(x) { this.q = x }
+};
+o[2] = {c: 7};
+var m = createSimpleMembrane(o);
+var w = m.wrapper;
+print("o =", str(o))
+print("w =", str(w));
+
+var f = w.f;
+var x = f(66);
+var x = f({a: 1});
+var x = w.f({a: 1});
+var a = x.a;
+assertEquals(6, w.a);
+assertEquals(8, w.b.bb);
+assertEquals(7, w[2]["c"]);
+assertEquals(undefined, w.c);
+assertEquals(1, w.f(1));
+assertEquals(1, w.f({a: 1}).a);
+assertEquals(2, w.g({a: 2}));
+assertEquals(3, (w.r = {a: 3}).a);
+assertEquals(3, w.r.a);
+assertEquals(3, o.r.a);
+w.h(3);
+assertEquals(3, w.q);
+assertEquals(3, o.q);
+assertEquals(4, (new w.h(4)).q);
+
+var wb = w.b;
+var wr = w.r;
+var wf = w.f;
+var wf3 = w.f(3);
+var wfx = w.f({a: 6});
+var wgx = w.g({a: {aa: 7}});
+var wh4 = new w.h(4);
+m.gate.disable();
+assertEquals(3, wf3);
+assertThrows(function() { w.a }, Error);
+assertThrows(function() { w.r }, Error);
+assertThrows(function() { w.r = {a: 4} }, Error);
+assertThrows(function() { o.r.a }, Error);
+assertEquals("object", typeof o.r);
+assertEquals(5, (o.r = {a: 5}).a);
+assertEquals(5, o.r.a);
+assertThrows(function() { w[1] }, Error);
+assertThrows(function() { w.c }, Error);
+assertThrows(function() { wb.bb }, Error);
+assertThrows(function() { wr.a }, Error);
+assertThrows(function() { wf(4) }, Error);
+assertThrows(function() { wfx.a }, Error);
+assertThrows(function() { wgx.aa }, Error);
+assertThrows(function() { wh4.q }, Error);
+
+m.gate.enable();
+assertEquals(6, w.a);
+assertEquals(5, w.r.a);
+assertEquals(5, o.r.a);
+assertEquals(7, w.r = 7);
+assertEquals(7, w.r);
+assertEquals(7, o.r);
+assertEquals(8, w.b.bb);
+assertEquals(7, w[2]["c"]);
+assertEquals(undefined, w.c);
+assertEquals(8, wb.bb);
+assertEquals(3, wr.a);
+assertEquals(4, wf(4));
+assertEquals(3, wf3);
+assertEquals(6, wfx.a);
+assertEquals(7, wgx.aa);
+assertEquals(4, wh4.q);
+
+
+// An identity-preserving membrane. Adapted from:
+// http://wiki.ecmascript.org/doku.php?id=harmony:proxies#an_identity-preserving_membrane
+
+function createMembrane(wetTarget) {
+  var wet2dry = WeakMap();
+  var dry2wet = WeakMap();
+
+  function asDry(obj) {
+    registerObject(obj)
+    print("asDry enter", str(obj))
+    try {
+      var x = asDry2(obj);
+      registerObject(x, "dry");
+      print("asDry exit", str(obj), "as", str(x));
+      return x;
+    } catch(e) {
+      print("asDry exception", str(e));
+      throw e;
+    }
+  }
+  function asDry2(wet) {
+    if (wet !== Object(wet)) {
+      // primitives provide only irrevocable knowledge, so don't
+      // bother wrapping it.
+      return wet;
+    }
+    var dryResult = wet2dry.get(wet);
+    if (dryResult) { return dryResult; }
+
+    var wetHandler = createHandler(wet);
+    var dryRevokeHandler = Proxy.create(Object.freeze({
+      get: function(receiver, name) {
+        return function() {
+          var arg = (name === "get" || name == "set") ? arguments[1] : "";
+          print("dry handler enter", name, arg);
+          var optWetHandler = dry2wet.get(dryRevokeHandler);
+          try {
+            var x = asDry(optWetHandler[name].apply(
+              optWetHandler, Array.prototype.map.call(arguments, asWet)));
+            print("dry handler exit", name, arg, "returning", str(x));
+            return x;
+          } catch (eWet) {
+            var x = asDry(eWet);
+            print("dry handler exception", name, arg, "throwing", str(x));
+            throw x;
+          }
+        };
+      }
+    }));
+    dry2wet.set(dryRevokeHandler, wetHandler);
+
+    if (typeof wet === "function") {
+      function callTrap() {
+        print("dry call trap enter", str(this));
+        var x = asDry(wet.apply(
+          asWet(this), Array.prototype.map.call(arguments, asWet)));
+        print("dry call trap exit", str(this), "returning", str(x));
+        return x;
+      }
+      function constructTrap() {
+        function forward(args) { return wet.apply(this, args) }
+        return asDry(new forward(Array.prototype.map.call(arguments, asWet)));
+      }
+      dryResult =
+        Proxy.createFunction(dryRevokeHandler, callTrap, constructTrap);
+    } else {
+      dryResult =
+        Proxy.create(dryRevokeHandler, asDry(Object.getPrototypeOf(wet)));
+    }
+    wet2dry.set(wet, dryResult);
+    dry2wet.set(dryResult, wet);
+    return dryResult;
+  }
+
+  function asWet(obj) {
+    registerObject(obj)
+    print("asWet enter", str(obj))
+    try {
+      var x = asWet2(obj)
+      registerObject(x, "wet")
+      print("asWet exit", str(obj), "as", str(x))
+      return x
+    } catch(e) {
+      print("asWet exception", str(e))
+      throw e
+    }
+  }
+  function asWet2(dry) {
+    if (dry !== Object(dry)) {
+      // primitives provide only irrevocable knowledge, so don't
+      // bother wrapping it.
+      return dry;
+    }
+    var wetResult = dry2wet.get(dry);
+    if (wetResult) { return wetResult; }
+
+    var dryHandler = createHandler(dry);
+    var wetRevokeHandler = Proxy.create(Object.freeze({
+      get: function(receiver, name) {
+        return function() {
+          var arg = (name === "get" || name == "set") ? arguments[1] : "";
+          print("wet handler enter", name, arg);
+          var optDryHandler = wet2dry.get(wetRevokeHandler);
+          try {
+            var x = asWet(optDryHandler[name].apply(
+              optDryHandler, Array.prototype.map.call(arguments, asDry)));
+            print("wet handler exit", name, arg, "returning", str(x));
+            return x;
+          } catch (eDry) {
+            var x = asWet(eDry);
+            print("wet handler exception", name, arg, "throwing", str(x));
+            throw x;
+          }
+        };
+      }
+    }));
+    wet2dry.set(wetRevokeHandler, dryHandler);
+
+    if (typeof dry === "function") {
+      function callTrap() {
+        print("wet call trap enter", str(this));
+        var x = asWet(dry.apply(
+          asDry(this), Array.prototype.map.call(arguments, asDry)));
+        print("wet call trap exit", str(this), "returning", str(x));
+        return x;
+      }
+      function constructTrap() {
+        function forward(args) { return dry.apply(this, args) }
+        return asWet(new forward(Array.prototype.map.call(arguments, asDry)));
+      }
+      wetResult =
+        Proxy.createFunction(wetRevokeHandler, callTrap, constructTrap);
+    } else {
+      wetResult =
+        Proxy.create(wetRevokeHandler, asWet(Object.getPrototypeOf(dry)));
+    }
+    dry2wet.set(dry, wetResult);
+    wet2dry.set(wetResult, dry);
+    return wetResult;
+  }
+
+  var gate = Object.freeze({
+    revoke: function() {
+      dry2wet = wet2dry = Object.freeze({
+        get: function(key) { throw new Error("revoked"); },
+        set: function(key, val) { throw new Error("revoked"); }
+      });
+    }
+  });
+
+  return Object.freeze({ wrapper: asDry(wetTarget), gate: gate });
+}
+
+
+var receiver
+var argument
+var o = {
+  a: 6,
+  b: {bb: 8},
+  f: function(x) { receiver = this; argument = x; return x },
+  g: function(x) { receiver = this; argument = x; return x.a },
+  h: function(x) { receiver = this; argument = x; this.q = x },
+  s: function(x) { receiver = this; argument = x; this.x = {y: x}; return this }
+}
+o[2] = {c: 7}
+var m = createMembrane(o)
+var w = m.wrapper
+print("o =", str(o))
+print("w =", str(w))
+
+var f = w.f
+var x = f(66)
+var x = f({a: 1})
+var x = w.f({a: 1})
+var a = x.a
+assertEquals(6, w.a)
+assertEquals(8, w.b.bb)
+assertEquals(7, w[2]["c"])
+assertEquals(undefined, w.c)
+assertEquals(1, w.f(1))
+assertSame(o, receiver)
+assertEquals(1, w.f({a: 1}).a)
+assertSame(o, receiver)
+assertEquals(2, w.g({a: 2}))
+assertSame(o, receiver)
+assertSame(w, w.f(w))
+assertSame(o, receiver)
+assertSame(o, argument)
+assertSame(o, w.f(o))
+assertSame(o, receiver)
+// Note that argument !== o, since o isn't dry, so gets wrapped wet again.
+assertEquals(3, (w.r = {a: 3}).a)
+assertEquals(3, w.r.a)
+assertEquals(3, o.r.a)
+w.h(3)
+assertEquals(3, w.q)
+assertEquals(3, o.q)
+assertEquals(4, (new w.h(4)).q)
+assertEquals(5, w.s(5).x.y)
+assertSame(o, receiver)
+
+var wb = w.b
+var wr = w.r
+var wf = w.f
+var wf3 = w.f(3)
+var wfx = w.f({a: 6})
+var wgx = w.g({a: {aa: 7}})
+var wh4 = new w.h(4)
+var ws5 = w.s(5)
+var ws5x = ws5.x
+m.gate.revoke()
+assertEquals(3, wf3)
+assertThrows(function() { w.a }, Error)
+assertThrows(function() { w.r }, Error)
+assertThrows(function() { w.r = {a: 4} }, Error)
+assertThrows(function() { o.r.a }, Error)
+assertEquals("object", typeof o.r)
+assertEquals(5, (o.r = {a: 5}).a)
+assertEquals(5, o.r.a)
+assertThrows(function() { w[1] }, Error)
+assertThrows(function() { w.c }, Error)
+assertThrows(function() { wb.bb }, Error)
+assertEquals(3, wr.a)
+assertThrows(function() { wf(4) }, Error)
+assertEquals(6, wfx.a)
+assertEquals(7, wgx.aa)
+assertThrows(function() { wh4.q }, Error)
+assertThrows(function() { ws5.x }, Error)
+assertThrows(function() { ws5x.y }, Error)
diff --git a/test/mjsunit/harmony/proxies-for.js b/test/mjsunit/harmony/proxies-for.js
new file mode 100644
index 0000000..3d419c6
--- /dev/null
+++ b/test/mjsunit/harmony/proxies-for.js
@@ -0,0 +1,168 @@
+// 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: --harmony-proxies
+
+
+// Helper.
+
+function TestWithProxies(test, x, y, z) {
+  test(Proxy.create, x, y, z)
+  test(function(h) {return Proxy.createFunction(h, function() {})}, x, y, z)
+}
+
+
+// Iterate over a proxy.
+
+function TestForIn(properties, handler) {
+  TestWithProxies(TestForIn2, properties, handler)
+}
+
+function TestForIn2(create, properties, handler) {
+  var p = create(handler)
+  var found = []
+  for (var x in p) found.push(x)
+  assertArrayEquals(properties, found)
+}
+
+TestForIn(["0", "a"], {
+  enumerate: function() { return [0, "a"] }
+})
+
+TestForIn(["null", "a"], {
+  enumerate: function() { return this.enumerate2() },
+  enumerate2: function() { return [null, "a"] }
+})
+
+TestForIn(["b", "d"], {
+  getPropertyNames: function() { return ["a", "b", "c", "d", "e"] },
+  getPropertyDescriptor: function(k) {
+    switch (k) {
+      case "a": return {enumerable: false, value: "3"};
+      case "b": return {enumerable: true, get get() {}};
+      case "c": return {value: 4};
+      case "d": return {get enumerable() { return true }};
+      default: return undefined;
+    }
+  }
+})
+
+TestForIn(["b", "a", "0", "c"], Proxy.create({
+  get: function(pr, pk) {
+    return function() { return ["b", "a", 0, "c"] }
+  }
+}))
+
+
+
+// Iterate over an object with a proxy prototype.
+
+function TestForInDerived(properties, handler) {
+  TestWithProxies(TestForInDerived2, properties, handler)
+}
+
+function TestForInDerived2(create, properties, handler) {
+  var p = create(handler)
+  var o = Object.create(p)
+  o.z = 0
+  var found = []
+  for (var x in o) found.push(x)
+  assertArrayEquals(["z"].concat(properties), found)
+
+  var oo = Object.create(o)
+  oo.y = 0
+  var found = []
+  for (var x in oo) found.push(x)
+  assertArrayEquals(["y", "z"].concat(properties), found)
+}
+
+TestForInDerived(["0", "a"], {
+  enumerate: function() { return [0, "a"] },
+  getPropertyDescriptor: function(k) {
+    return k == "0" || k == "a" ? {} : undefined
+  }
+})
+
+TestForInDerived(["null", "a"], {
+  enumerate: function() { return this.enumerate2() },
+  enumerate2: function() { return [null, "a"] },
+  getPropertyDescriptor: function(k) {
+    return k == "null" || k == "a" ? {} : undefined
+  }
+})
+
+TestForInDerived(["b", "d"], {
+  getPropertyNames: function() { return ["a", "b", "c", "d", "e"] },
+  getPropertyDescriptor: function(k) {
+    switch (k) {
+      case "a": return {enumerable: false, value: "3"};
+      case "b": return {enumerable: true, get get() {}};
+      case "c": return {value: 4};
+      case "d": return {get enumerable() { return true }};
+      default: return undefined;
+    }
+  }
+})
+
+
+
+// Throw exception in enumerate trap.
+
+function TestForInThrow(handler) {
+  TestWithProxies(TestForInThrow2, handler)
+}
+
+function TestForInThrow2(create, handler) {
+  var p = create(handler)
+  var o = Object.create(p)
+  assertThrows(function(){ for (var x in p) {} }, "myexn")
+  assertThrows(function(){ for (var x in o) {} }, "myexn")
+}
+
+TestForInThrow({
+  enumerate: function() { throw "myexn" }
+})
+
+TestForInThrow({
+  enumerate: function() { return this.enumerate2() },
+  enumerate2: function() { throw "myexn" }
+})
+
+TestForInThrow({
+  getPropertyNames: function() { throw "myexn" }
+})
+
+TestForInThrow({
+  getPropertyNames: function() { return ["a"] },
+  getPropertyDescriptor: function() { throw "myexn" }
+})
+
+TestForInThrow(Proxy.create({
+  get: function(pr, pk) {
+    return function() { throw "myexn" }
+  }
+}))
diff --git a/test/mjsunit/harmony/proxies-function.js b/test/mjsunit/harmony/proxies-function.js
new file mode 100644
index 0000000..3f5ace6
--- /dev/null
+++ b/test/mjsunit/harmony/proxies-function.js
@@ -0,0 +1,732 @@
+// 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: --harmony-proxies --allow-natives-syntax
+
+
+// Helper.
+
+function CreateFrozen(handler, callTrap, constructTrap) {
+  if (handler.fix === undefined) handler.fix = function() { return {} }
+  var f = Proxy.createFunction(handler, callTrap, constructTrap)
+  Object.freeze(f)
+  return f
+}
+
+
+// Ensures that checking the "length" property of a function proxy doesn't
+// crash due to lack of a [[Get]] method.
+var handler = {
+  get : function(r, n) { return n == "length" ? 2 : undefined }
+}
+
+
+// Calling (call, Function.prototype.call, Function.prototype.apply,
+//          Function.prototype.bind).
+
+var global_object = this
+var receiver
+
+function TestCall(isStrict, callTrap) {
+  assertEquals(42, callTrap(5, 37))
+  // TODO(rossberg): strict mode seems to be broken on x64...
+  // assertSame(isStrict ? undefined : global_object, receiver)
+
+  var handler = {
+    get: function(r, k) {
+      return k == "length" ? 2 : Function.prototype[k]
+    }
+  }
+  var f = Proxy.createFunction(handler, callTrap)
+  var o = {f: f}
+  global_object.f = f
+
+  receiver = 333
+  assertEquals(42, f(11, 31))
+  // TODO(rossberg): strict mode seems to be broken on x64...
+  // assertSame(isStrict ? undefined : global_object, receiver)
+  receiver = 333
+  assertEquals(42, o.f(10, 32))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(42, o["f"](9, 33))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(42, (1, o).f(8, 34))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(42, (1, o)["f"](7, 35))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(42, f.call(o, 32, 10))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(42, f.call(undefined, 33, 9))
+  assertSame(isStrict ? undefined : global_object, receiver)
+  receiver = 333
+  assertEquals(42, f.call(null, 33, 9))
+  assertSame(isStrict ? null : global_object, receiver)
+  receiver = 333
+  assertEquals(44, f.call(2, 21, 23))
+  assertSame(2, receiver.valueOf())
+  receiver = 333
+  assertEquals(42, Function.prototype.call.call(f, o, 20, 22))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(43, Function.prototype.call.call(f, null, 20, 23))
+  assertSame(isStrict ? null : global_object, receiver)
+  assertEquals(44, Function.prototype.call.call(f, 2, 21, 23))
+  assertEquals(2, receiver.valueOf())
+  receiver = 333
+  assertEquals(32, f.apply(o, [16, 16]))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(32, Function.prototype.apply.call(f, o, [17, 15]))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(42, %Call(o, 11, 31, f))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(42, %Call(null, 11, 31, f))
+  assertSame(isStrict ? null : global_object, receiver)
+  receiver = 333
+  assertEquals(42, %Apply(f, o, [11, 31], 0, 2))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(42, %Apply(f, null, [11, 31], 0, 2))
+  assertSame(isStrict ? null : global_object, receiver)
+  receiver = 333
+  assertEquals(42, %_CallFunction(o, 11, 31, f))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(42, %_CallFunction(null, 11, 31, f))
+  assertSame(isStrict ? null : global_object, receiver)
+
+  var ff = Function.prototype.bind.call(f, o, 12)
+  assertTrue(ff.length <= 1)  // TODO(rossberg): Not spec'ed yet, be lax.
+  receiver = 333
+  assertEquals(42, ff(30))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(33, Function.prototype.call.call(ff, {}, 21))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(32, Function.prototype.apply.call(ff, {}, [20]))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(23, %Call({}, 11, ff))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(23, %Call({}, 11, 3, ff))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(24, %Apply(ff, {}, [12, 13], 0, 1))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(24, %Apply(ff, {}, [12, 13], 0, 2))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(34, %_CallFunction({}, 22, ff))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(34, %_CallFunction({}, 22, 3, ff))
+  assertSame(o, receiver)
+
+  var fff = Function.prototype.bind.call(ff, o, 30)
+  assertEquals(0, fff.length)
+  receiver = 333
+  assertEquals(42, fff())
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(42, Function.prototype.call.call(fff, {}))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(42, Function.prototype.apply.call(fff, {}))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(42, %Call({}, fff))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(42, %Call({}, 11, 3, fff))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(42, %Apply(fff, {}, [], 0, 0))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(42, %Apply(fff, {}, [12, 13], 0, 0))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(42, %Apply(fff, {}, [12, 13], 0, 2))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(42, %_CallFunction({}, fff))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(42, %_CallFunction({}, 3, 4, 5, fff))
+  assertSame(o, receiver)
+
+  var f = CreateFrozen({}, callTrap)
+  receiver = 333
+  assertEquals(42, f(11, 31))
+  assertSame(isStrict ? undefined : global_object, receiver)
+  var o = {f: f}
+  receiver = 333
+  assertEquals(42, o.f(10, 32))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(42, o["f"](9, 33))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(42, (1, o).f(8, 34))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(42, (1, o)["f"](7, 35))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(42, Function.prototype.call.call(f, o, 20, 22))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(32, Function.prototype.apply.call(f, o, [17, 15]))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(23, %Call(o, 11, 12, f))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(27, %Apply(f, o, [12, 13, 14], 1, 2))
+  assertSame(o, receiver)
+  receiver = 333
+  assertEquals(42, %_CallFunction(o, 18, 24, f))
+  assertSame(o, receiver)
+}
+
+TestCall(false, function(x, y) {
+  receiver = this
+  return x + y
+})
+
+TestCall(true, function(x, y) {
+  "use strict"
+  receiver = this
+  return x + y
+})
+
+TestCall(false, function() {
+  receiver = this
+  return arguments[0] + arguments[1]
+})
+
+TestCall(false, Proxy.createFunction(handler, function(x, y) {
+  receiver = this
+  return x + y
+}))
+
+TestCall(true, Proxy.createFunction(handler, function(x, y) {
+  "use strict"
+  receiver = this
+  return x + y
+}))
+
+TestCall(false, CreateFrozen(handler, function(x, y) {
+  receiver = this
+  return x + y
+}))
+
+
+
+// Using intrinsics as call traps.
+
+function TestCallIntrinsic(type, callTrap) {
+  var f = Proxy.createFunction({}, callTrap)
+  var x = f()
+  assertTrue(typeof x == type)
+}
+
+TestCallIntrinsic("boolean", Boolean)
+TestCallIntrinsic("number", Number)
+TestCallIntrinsic("string", String)
+TestCallIntrinsic("object", Object)
+TestCallIntrinsic("function", Function)
+
+
+
+// Throwing from call trap.
+
+function TestCallThrow(callTrap) {
+  var f = Proxy.createFunction({}, callTrap)
+  assertThrows(function(){ f(11) }, "myexn")
+  assertThrows(function(){ ({x: f}).x(11) }, "myexn")
+  assertThrows(function(){ ({x: f})["x"](11) }, "myexn")
+  assertThrows(function(){ Function.prototype.call.call(f, {}, 2) }, "myexn")
+  assertThrows(function(){ Function.prototype.apply.call(f, {}, [1]) }, "myexn")
+  assertThrows(function(){ %Call({}, f) }, "myexn")
+  assertThrows(function(){ %Call({}, 1, 2, f) }, "myexn")
+  assertThrows(function(){ %Apply({}, f, [], 3, 0) }, "myexn")
+  assertThrows(function(){ %Apply({}, f, [3, 4], 0, 1) }, "myexn")
+  assertThrows(function(){ %_CallFunction({}, f) }, "myexn")
+  assertThrows(function(){ %_CallFunction({}, 1, 2, f) }, "myexn")
+
+  var f = CreateFrozen({}, callTrap)
+  assertThrows(function(){ f(11) }, "myexn")
+  assertThrows(function(){ ({x: f}).x(11) }, "myexn")
+  assertThrows(function(){ ({x: f})["x"](11) }, "myexn")
+  assertThrows(function(){ Function.prototype.call.call(f, {}, 2) }, "myexn")
+  assertThrows(function(){ Function.prototype.apply.call(f, {}, [1]) }, "myexn")
+  assertThrows(function(){ %Call({}, f) }, "myexn")
+  assertThrows(function(){ %Call({}, 1, 2, f) }, "myexn")
+  assertThrows(function(){ %Apply({}, f, [], 3, 0) }, "myexn")
+  assertThrows(function(){ %Apply({}, f, [3, 4], 0, 1) }, "myexn")
+  assertThrows(function(){ %_CallFunction({}, f) }, "myexn")
+  assertThrows(function(){ %_CallFunction({}, 1, 2, f) }, "myexn")
+}
+
+TestCallThrow(function() { throw "myexn" })
+TestCallThrow(Proxy.createFunction({}, function() { throw "myexn" }))
+TestCallThrow(CreateFrozen({}, function() { throw "myexn" }))
+
+
+
+// Construction (new).
+
+var prototype = {myprop: 0}
+var receiver
+
+var handlerWithPrototype = {
+  fix: function() { return { prototype: { value: prototype } }; },
+  get: function(r, n) {
+    if (n == "length") return 2;
+    assertEquals("prototype", n);
+    return prototype;
+  }
+}
+
+var handlerSansPrototype = {
+  fix: function() { return { length: { value: 2 } } },
+  get: function(r, n) {
+    if (n == "length") return 2;
+    assertEquals("prototype", n);
+    return undefined;
+  }
+}
+
+function ReturnUndef(x, y) {
+  "use strict";
+  receiver = this;
+  this.sum = x + y;
+}
+
+function ReturnThis(x, y) {
+  "use strict";
+  receiver = this;
+  this.sum = x + y;
+  return this;
+}
+
+function ReturnNew(x, y) {
+  "use strict";
+  receiver = this;
+  return {sum: x + y};
+}
+
+function ReturnNewWithProto(x, y) {
+  "use strict";
+  receiver = this;
+  var result = Object.create(prototype);
+  result.sum = x + y;
+  return result;
+}
+
+function TestConstruct(proto, constructTrap) {
+  TestConstruct2(proto, constructTrap, handlerWithPrototype)
+  TestConstruct2(proto, constructTrap, handlerSansPrototype)
+}
+
+function TestConstruct2(proto, constructTrap, handler) {
+  var f = Proxy.createFunction(handler, function() {}, constructTrap)
+  var o = new f(11, 31)
+  assertEquals(undefined, receiver)
+  assertEquals(42, o.sum)
+  assertSame(proto, Object.getPrototypeOf(o))
+
+  var f = CreateFrozen(handler, function() {}, constructTrap)
+  var o = new f(11, 32)
+  assertEquals(undefined, receiver)
+  assertEquals(43, o.sum)
+  assertSame(proto, Object.getPrototypeOf(o))
+}
+
+TestConstruct(Object.prototype, ReturnNew)
+TestConstruct(prototype, ReturnNewWithProto)
+
+TestConstruct(Object.prototype, Proxy.createFunction(handler, ReturnNew))
+TestConstruct(prototype, Proxy.createFunction(handler, ReturnNewWithProto))
+
+TestConstruct(Object.prototype, CreateFrozen(handler, ReturnNew))
+TestConstruct(prototype, CreateFrozen(handler, ReturnNewWithProto))
+
+
+
+// Construction with derived construct trap.
+
+function TestConstructFromCall(proto, returnsThis, callTrap) {
+  TestConstructFromCall2(prototype, returnsThis, callTrap, handlerWithPrototype)
+  TestConstructFromCall2(proto, returnsThis, callTrap, handlerSansPrototype)
+}
+
+function TestConstructFromCall2(proto, returnsThis, callTrap, handler) {
+  // TODO(rossberg): handling of prototype for derived construct trap will be
+  // fixed in a separate change. Commenting out checks below for now.
+  var f = Proxy.createFunction(handler, callTrap)
+  var o = new f(11, 31)
+  if (returnsThis) assertEquals(o, receiver)
+  assertEquals(42, o.sum)
+  // assertSame(proto, Object.getPrototypeOf(o))
+
+  var g = CreateFrozen(handler, callTrap)
+  // assertSame(f.prototype, g.prototype)
+  var o = new g(11, 32)
+  if (returnsThis) assertEquals(o, receiver)
+  assertEquals(43, o.sum)
+  // assertSame(proto, Object.getPrototypeOf(o))
+}
+
+TestConstructFromCall(Object.prototype, true, ReturnUndef)
+TestConstructFromCall(Object.prototype, true, ReturnThis)
+TestConstructFromCall(Object.prototype, false, ReturnNew)
+TestConstructFromCall(prototype, false, ReturnNewWithProto)
+
+TestConstructFromCall(Object.prototype, true,
+                      Proxy.createFunction(handler, ReturnUndef))
+TestConstructFromCall(Object.prototype, true,
+                      Proxy.createFunction(handler, ReturnThis))
+TestConstructFromCall(Object.prototype, false,
+                      Proxy.createFunction(handler, ReturnNew))
+TestConstructFromCall(prototype, false,
+                      Proxy.createFunction(handler, ReturnNewWithProto))
+
+TestConstructFromCall(Object.prototype, true, CreateFrozen({}, ReturnUndef))
+TestConstructFromCall(Object.prototype, true, CreateFrozen({}, ReturnThis))
+TestConstructFromCall(Object.prototype, false, CreateFrozen({}, ReturnNew))
+TestConstructFromCall(prototype, false, CreateFrozen({}, ReturnNewWithProto))
+
+ReturnUndef.prototype = prototype
+ReturnThis.prototype = prototype
+ReturnNew.prototype = prototype
+ReturnNewWithProto.prototype = prototype
+
+TestConstructFromCall(prototype, true, ReturnUndef)
+TestConstructFromCall(prototype, true, ReturnThis)
+TestConstructFromCall(Object.prototype, false, ReturnNew)
+TestConstructFromCall(prototype, false, ReturnNewWithProto)
+
+TestConstructFromCall(Object.prototype, true,
+                      Proxy.createFunction(handler, ReturnUndef))
+TestConstructFromCall(Object.prototype, true,
+                      Proxy.createFunction(handler, ReturnThis))
+TestConstructFromCall(Object.prototype, false,
+                      Proxy.createFunction(handler, ReturnNew))
+TestConstructFromCall(prototype, false,
+                      Proxy.createFunction(handler, ReturnNewWithProto))
+
+TestConstructFromCall(prototype, true,
+                      Proxy.createFunction(handlerWithPrototype, ReturnUndef))
+TestConstructFromCall(prototype, true,
+                      Proxy.createFunction(handlerWithPrototype, ReturnThis))
+TestConstructFromCall(Object.prototype, false,
+                      Proxy.createFunction(handlerWithPrototype, ReturnNew))
+TestConstructFromCall(prototype, false,
+                      Proxy.createFunction(handlerWithPrototype,
+                                           ReturnNewWithProto))
+
+TestConstructFromCall(prototype, true,
+                      CreateFrozen(handlerWithPrototype, ReturnUndef))
+TestConstructFromCall(prototype, true,
+                      CreateFrozen(handlerWithPrototype, ReturnThis))
+TestConstructFromCall(Object.prototype, false,
+                      CreateFrozen(handlerWithPrototype, ReturnNew))
+TestConstructFromCall(prototype, false,
+                      CreateFrozen(handlerWithPrototype, ReturnNewWithProto))
+
+
+
+// Throwing from the construct trap.
+
+function TestConstructThrow(trap) {
+  TestConstructThrow2(Proxy.createFunction({ fix: function() {return {};} },
+                                           trap))
+  TestConstructThrow2(Proxy.createFunction({ fix: function() {return {};} },
+                                           function() {},
+                                           trap))
+}
+
+function TestConstructThrow2(f) {
+  assertThrows(function(){ new f(11) }, "myexn")
+  Object.freeze(f)
+  assertThrows(function(){ new f(11) }, "myexn")
+}
+
+TestConstructThrow(function() { throw "myexn" })
+TestConstructThrow(Proxy.createFunction({}, function() { throw "myexn" }))
+TestConstructThrow(CreateFrozen({}, function() { throw "myexn" }))
+
+
+
+// Using function proxies as getters and setters.
+
+var value
+var receiver
+
+function TestAccessorCall(getterCallTrap, setterCallTrap) {
+  var handler = { fix: function() { return {} } }
+  var pgetter = Proxy.createFunction(handler, getterCallTrap)
+  var psetter = Proxy.createFunction(handler, setterCallTrap)
+
+  var o = {}
+  var oo = Object.create(o)
+  Object.defineProperty(o, "a", {get: pgetter, set: psetter})
+  Object.defineProperty(o, "b", {get: pgetter})
+  Object.defineProperty(o, "c", {set: psetter})
+  Object.defineProperty(o, "3", {get: pgetter, set: psetter})
+  Object.defineProperty(oo, "a", {value: 43})
+
+  receiver = ""
+  assertEquals(42, o.a)
+  assertSame(o, receiver)
+  receiver = ""
+  assertEquals(42, o.b)
+  assertSame(o, receiver)
+  receiver = ""
+  assertEquals(undefined, o.c)
+  assertEquals("", receiver)
+  receiver = ""
+  assertEquals(42, o["a"])
+  assertSame(o, receiver)
+  receiver = ""
+  assertEquals(42, o[3])
+  assertSame(o, receiver)
+
+  receiver = ""
+  assertEquals(43, oo.a)
+  assertEquals("", receiver)
+  receiver = ""
+  assertEquals(42, oo.b)
+  assertSame(oo, receiver)
+  receiver = ""
+  assertEquals(undefined, oo.c)
+  assertEquals("", receiver)
+  receiver = ""
+  assertEquals(43, oo["a"])
+  assertEquals("", receiver)
+  receiver = ""
+  assertEquals(42, oo[3])
+  assertSame(oo, receiver)
+
+  receiver = ""
+  assertEquals(50, o.a = 50)
+  assertSame(o, receiver)
+  assertEquals(50, value)
+  receiver = ""
+  assertEquals(51, o.b = 51)
+  assertEquals("", receiver)
+  assertEquals(50, value)  // no setter
+  assertThrows(function() { "use strict"; o.b = 51 }, TypeError)
+  receiver = ""
+  assertEquals(52, o.c = 52)
+  assertSame(o, receiver)
+  assertEquals(52, value)
+  receiver = ""
+  assertEquals(53, o["a"] = 53)
+  assertSame(o, receiver)
+  assertEquals(53, value)
+  receiver = ""
+  assertEquals(54, o[3] = 54)
+  assertSame(o, receiver)
+  assertEquals(54, value)
+
+  value = 0
+  receiver = ""
+  assertEquals(60, oo.a = 60)
+  assertEquals("", receiver)
+  assertEquals(0, value)  // oo has own 'a'
+  assertEquals(61, oo.b = 61)
+  assertSame("", receiver)
+  assertEquals(0, value)  // no setter
+  assertThrows(function() { "use strict"; oo.b = 61 }, TypeError)
+  receiver = ""
+  assertEquals(62, oo.c = 62)
+  assertSame(oo, receiver)
+  assertEquals(62, value)
+  receiver = ""
+  assertEquals(63, oo["c"] = 63)
+  assertSame(oo, receiver)
+  assertEquals(63, value)
+  receiver = ""
+  assertEquals(64, oo[3] = 64)
+  assertSame(oo, receiver)
+  assertEquals(64, value)
+}
+
+TestAccessorCall(
+  function() { receiver = this; return 42 },
+  function(x) { receiver = this; value = x }
+)
+
+TestAccessorCall(
+  function() { "use strict"; receiver = this; return 42 },
+  function(x) { "use strict"; receiver = this; value = x }
+)
+
+TestAccessorCall(
+  Proxy.createFunction({}, function() { receiver = this; return 42 }),
+  Proxy.createFunction({}, function(x) { receiver = this; value = x })
+)
+
+TestAccessorCall(
+  CreateFrozen({}, function() { receiver = this; return 42 }),
+  CreateFrozen({}, function(x) { receiver = this; value = x })
+)
+
+
+
+// TODO(rossberg): Ultimately, I want to have the following test function
+// run through, but it currently fails on so many cases (some not even
+// involving proxies), that I leave that for later...
+/*
+function TestCalls() {
+  var handler = {
+    get: function(r, k) {
+      return k == "length" ? 2 : Function.prototype[k]
+    }
+  }
+  var bind = Function.prototype.bind
+  var o = {}
+
+  var traps = [
+    function(x, y) {
+      return {receiver: this, result: x + y, strict: false}
+    },
+    function(x, y) { "use strict";
+      return {receiver: this, result: x + y, strict: true}
+    },
+    function() {
+      var x = arguments[0], y = arguments[1]
+      return {receiver: this, result: x + y, strict: false}
+    },
+    Proxy.createFunction(handler, function(x, y) {
+      return {receiver: this, result: x + y, strict: false}
+    }),
+    Proxy.createFunction(handler, function() {
+      var x = arguments[0], y = arguments[1]
+      return {receiver: this, result: x + y, strict: false}
+    }),
+    Proxy.createFunction(handler, function(x, y) { "use strict"
+      return {receiver: this, result: x + y, strict: true}
+    }),
+    CreateFrozen(handler, function(x, y) {
+      return {receiver: this, result: x + y, strict: false}
+    }),
+    CreateFrozen(handler, function(x, y) { "use strict"
+      return {receiver: this, result: x + y, strict: true}
+    }),
+  ]
+  var creates = [
+    function(trap) { return trap },
+    function(trap) { return CreateFrozen({}, callTrap) },
+    function(trap) { return Proxy.createFunction(handler, callTrap) },
+    function(trap) {
+      return Proxy.createFunction(handler, CreateFrozen({}, callTrap))
+    },
+    function(trap) {
+      return Proxy.createFunction(handler, Proxy.createFunction(handler, callTrap))
+    },
+  ]
+  var binds = [
+    function(f, o, x, y) { return f },
+    function(f, o, x, y) { return bind.call(f, o) },
+    function(f, o, x, y) { return bind.call(f, o, x) },
+    function(f, o, x, y) { return bind.call(f, o, x, y) },
+    function(f, o, x, y) { return bind.call(f, o, x, y, 5) },
+    function(f, o, x, y) { return bind.call(bind.call(f, o), {}, x, y) },
+    function(f, o, x, y) { return bind.call(bind.call(f, o, x), {}, y) },
+    function(f, o, x, y) { return bind.call(bind.call(f, o, x, y), {}, 5) },
+  ]
+  var calls = [
+    function(f, x, y) { return f(x, y) },
+    function(f, x, y) { var g = f; return g(x, y) },
+    function(f, x, y) { with ({}) return f(x, y) },
+    function(f, x, y) { var g = f; with ({}) return g(x, y) },
+    function(f, x, y, o) { with (o) return f(x, y) },
+    function(f, x, y, o) { return f.call(o, x, y) },
+    function(f, x, y, o) { return f.apply(o, [x, y]) },
+    function(f, x, y, o) { return Function.prototype.call.call(f, o, x, y) },
+    function(f, x, y, o) { return Function.prototype.apply.call(f, o, [x, y]) },
+    function(f, x, y, o) { return %_CallFunction(o, x, y, f) },
+    function(f, x, y, o) { return %Call(o, x, y, f) },
+    function(f, x, y, o) { return %Apply(f, o, [null, x, y, null], 1, 2) },
+    function(f, x, y, o) { return %Apply(f, o, arguments, 2, 2) },
+    function(f, x, y, o) { if (typeof o == "object") return o.f(x, y) },
+    function(f, x, y, o) { if (typeof o == "object") return o["f"](x, y) },
+    function(f, x, y, o) { if (typeof o == "object") return (1, o).f(x, y) },
+    function(f, x, y, o) { if (typeof o == "object") return (1, o)["f"](x, y) },
+  ]
+  var receivers = [o, global_object, undefined, null, 2, "bla", true]
+  var expectedNonStricts = [o, global_object, global_object, global_object]
+
+  for (var t = 0; t < traps.length; ++t) {
+    for (var i = 0; i < creates.length; ++i) {
+      for (var j = 0; j < binds.length; ++j) {
+        for (var k = 0; k < calls.length; ++k) {
+          for (var m = 0; m < receivers.length; ++m) {
+            for (var n = 0; n < receivers.length; ++n) {
+              var bound = receivers[m]
+              var receiver = receivers[n]
+              var func = binds[j](creates[i](traps[t]), bound, 31, 11)
+              var expected = j > 0 ? bound : receiver
+              var expectedNonStrict = expectedNonStricts[j > 0 ? m : n]
+              o.f = func
+              global_object.f = func
+              var x = calls[k](func, 11, 31, receiver)
+              if (x !== undefined) {
+                assertEquals(42, x.result)
+                if (calls[k].length < 4)
+                  assertSame(x.strict ? undefined : global_object, x.receiver)
+                else if (x.strict)
+                  assertSame(expected, x.receiver)
+                else if (expectedNonStrict === undefined)
+                  assertSame(expected, x.receiver.valueOf())
+                else
+                  assertSame(expectedNonStrict, x.receiver)
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+TestCalls()
+*/
diff --git a/test/mjsunit/harmony/proxies-hash.js b/test/mjsunit/harmony/proxies-hash.js
new file mode 100644
index 0000000..abfc0f5
--- /dev/null
+++ b/test/mjsunit/harmony/proxies-hash.js
@@ -0,0 +1,122 @@
+// 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: --harmony-proxies --harmony-collections
+
+
+// Helper.
+
+function TestWithProxies(test, construct, handler) {
+  test(construct, handler, Proxy.create)
+  test(construct, handler, function(h) {
+    return Proxy.createFunction(h, function() {})
+  })
+}
+
+
+// Sets.
+
+function TestSet(construct, fix) {
+  TestWithProxies(TestSet2, construct, fix)
+}
+
+function TestSet2(construct, fix, create) {
+  var handler = {fix: function() { return {} }}
+  var p1 = create(handler)
+  var p2 = create(handler)
+  var p3 = create(handler)
+  fix(p3)
+
+  var s = construct();
+  s.add(p1);
+  s.add(p2);
+  assertTrue(s.has(p1));
+  assertTrue(s.has(p2));
+  assertFalse(s.has(p3));
+
+  fix(p1)
+  fix(p2)
+  assertTrue(s.has(p1));
+  assertTrue(s.has(p2));
+  assertFalse(s.has(p3));
+
+  s.delete(p2);
+  assertTrue(s.has(p1));
+  assertFalse(s.has(p2));
+  assertFalse(s.has(p3));
+}
+
+TestSet(Set, Object.seal)
+TestSet(Set, Object.freeze)
+TestSet(Set, Object.preventExtensions)
+
+
+// Maps and weak maps.
+
+function TestMap(construct, fix) {
+  TestWithProxies(TestMap2, construct, fix)
+}
+
+function TestMap2(construct, fix, create) {
+  var handler = {fix: function() { return {} }}
+  var p1 = create(handler)
+  var p2 = create(handler)
+  var p3 = create(handler)
+  fix(p3)
+
+  var m = construct();
+  m.set(p1, 123);
+  m.set(p2, 321);
+  assertTrue(m.has(p1));
+  assertTrue(m.has(p2));
+  assertFalse(m.has(p3));
+  assertSame(123, m.get(p1));
+  assertSame(321, m.get(p2));
+
+  fix(p1)
+  fix(p2)
+  assertTrue(m.has(p1));
+  assertTrue(m.has(p2));
+  assertFalse(m.has(p3));
+  assertSame(123, m.get(p1));
+  assertSame(321, m.get(p2));
+
+  m.delete(p2);
+  assertTrue(m.has(p1));
+  assertFalse(m.has(p2));
+  assertFalse(m.has(p3));
+  assertSame(123, m.get(p1));
+  assertSame(undefined, m.get(p2));
+}
+
+TestMap(Map, Object.seal)
+TestMap(Map, Object.freeze)
+TestMap(Map, Object.preventExtensions)
+
+TestMap(WeakMap, Object.seal)
+TestMap(WeakMap, Object.freeze)
+TestMap(WeakMap, Object.preventExtensions)
diff --git a/test/mjsunit/harmony/proxies.js b/test/mjsunit/harmony/proxies.js
index 3c4e5f6..50c8613 100644
--- a/test/mjsunit/harmony/proxies.js
+++ b/test/mjsunit/harmony/proxies.js
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// 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:
@@ -28,70 +28,167 @@
 // Flags: --harmony-proxies
 
 
-// TODO(rossberg): for-in for proxies not implemented.
-// TODO(rossberg): inheritance from proxies not implemented.
-// TODO(rossberg): function proxies as constructors not implemented.
-
-
 // Helper.
 
-function TestWithProxies(test, handler) {
-  test(handler, Proxy.create)
-  test(handler, function(h) {return Proxy.createFunction(h, function() {})})
+function TestWithProxies(test, x, y, z) {
+  test(Proxy.create, x, y, z)
+  test(function(h) {return Proxy.createFunction(h, function() {})}, x, y, z)
 }
 
 
-// Getters.
+
+// Getting property descriptors (Object.getOwnPropertyDescriptor).
+
+var key
+
+function TestGetOwnProperty(handler) {
+  TestWithProxies(TestGetOwnProperty2, handler)
+}
+
+function TestGetOwnProperty2(create, handler) {
+  var p = create(handler)
+  assertEquals(42, Object.getOwnPropertyDescriptor(p, "a").value)
+  assertEquals("a", key)
+  assertEquals(42, Object.getOwnPropertyDescriptor(p, 99).value)
+  assertEquals("99", key)
+}
+
+TestGetOwnProperty({
+  getOwnPropertyDescriptor: function(k) {
+    key = k
+    return {value: 42, configurable: true}
+  }
+})
+
+TestGetOwnProperty({
+  getOwnPropertyDescriptor: function(k) {
+    return this.getOwnPropertyDescriptor2(k)
+  },
+  getOwnPropertyDescriptor2: function(k) {
+    key = k
+    return {value: 42, configurable: true}
+  }
+})
+
+TestGetOwnProperty({
+  getOwnPropertyDescriptor: function(k) {
+    key = k
+    return {get value() { return 42 }, get configurable() { return true }}
+  }
+})
+
+TestGetOwnProperty(Proxy.create({
+  get: function(pr, pk) {
+    return function(k) { key = k; return {value: 42, configurable: true} }
+  }
+}))
+
+
+function TestGetOwnPropertyThrow(handler) {
+  TestWithProxies(TestGetOwnPropertyThrow2, handler)
+}
+
+function TestGetOwnPropertyThrow2(create, handler) {
+  var p = create(handler)
+  assertThrows(function(){ Object.getOwnPropertyDescriptor(p, "a") }, "myexn")
+  assertThrows(function(){ Object.getOwnPropertyDescriptor(p, 77) }, "myexn")
+}
+
+TestGetOwnPropertyThrow({
+  getOwnPropertyDescriptor: function(k) { throw "myexn" }
+})
+
+TestGetOwnPropertyThrow({
+  getOwnPropertyDescriptor: function(k) {
+    return this.getPropertyDescriptor2(k)
+  },
+  getOwnPropertyDescriptor2: function(k) { throw "myexn" }
+})
+
+TestGetOwnPropertyThrow({
+  getOwnPropertyDescriptor: function(k) {
+    return {get value() { throw "myexn" }}
+  }
+})
+
+TestGetOwnPropertyThrow(Proxy.create({
+  get: function(pr, pk) {
+    return function(k) { throw "myexn" }
+  }
+}))
+
+
+
+// Getters (dot, brackets).
+
+var key
 
 function TestGet(handler) {
   TestWithProxies(TestGet2, handler)
 }
 
-function TestGet2(handler, create) {
+function TestGet2(create, handler) {
   var p = create(handler)
   assertEquals(42, p.a)
+  assertEquals("a", key)
   assertEquals(42, p["b"])
+  assertEquals("b", key)
+  assertEquals(42, p[99])
+  assertEquals("99", key)
+  assertEquals(42, (function(n) { return p[n] })("c"))
+  assertEquals("c", key)
+  assertEquals(42, (function(n) { return p[n] })(101))
+  assertEquals("101", key)
 
-  // TODO(rossberg): inheritance from proxies not yet implemented.
-  // var o = Object.create(p, {x: {value: 88}})
-  // assertEquals(42, o.a)
-  // assertEquals(42, o["b"])
-  // assertEquals(88, o.x)
-  // assertEquals(88, o["x"])
+  var o = Object.create(p, {x: {value: 88}})
+  assertEquals(42, o.a)
+  assertEquals("a", key)
+  assertEquals(42, o["b"])
+  assertEquals("b", key)
+  assertEquals(42, o[99])
+  assertEquals("99", key)
+  assertEquals(88, o.x)
+  assertEquals(88, o["x"])
+  assertEquals(42, (function(n) { return o[n] })("c"))
+  assertEquals("c", key)
+  assertEquals(42, (function(n) { return o[n] })(101))
+  assertEquals("101", key)
+  assertEquals(88, (function(n) { return o[n] })("x"))
 }
 
 TestGet({
-  get: function(r, k) { return 42 }
+  get: function(r, k) { key = k; return 42 }
 })
 
 TestGet({
   get: function(r, k) { return this.get2(r, k) },
-  get2: function(r, k) { return 42 }
+  get2: function(r, k) { key = k; return 42 }
 })
 
 TestGet({
-  getPropertyDescriptor: function(k) { return {value: 42} }
+  getPropertyDescriptor: function(k) { key = k; return {value: 42} }
 })
 
 TestGet({
   getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
-  getPropertyDescriptor2: function(k) { return {value: 42} }
+  getPropertyDescriptor2: function(k) { key = k; return {value: 42} }
 })
 
 TestGet({
   getPropertyDescriptor: function(k) {
+    key = k;
     return {get value() { return 42 }}
   }
 })
 
 TestGet({
   get: undefined,
-  getPropertyDescriptor: function(k) { return {value: 42} }
+  getPropertyDescriptor: function(k) { key = k; return {value: 42} }
 })
 
 TestGet(Proxy.create({
   get: function(pr, pk) {
-    return function(r, k) { return 42 }
+    return function(r, k) { key = k; return 42 }
   }
 }))
 
@@ -100,14 +197,43 @@
   TestWithProxies(TestGetCall2, handler)
 }
 
-function TestGetCall2(handler, create) {
+function TestGetCall2(create, handler) {
   var p = create(handler)
   assertEquals(55, p.f())
+  assertEquals(55, p["f"]())
   assertEquals(55, p.f("unused", "arguments"))
   assertEquals(55, p.f.call(p))
+  assertEquals(55, p["f"].call(p))
+  assertEquals(55, p[101].call(p))
   assertEquals(55, p.withargs(45, 5))
   assertEquals(55, p.withargs.call(p, 11, 22))
+  assertEquals(55, (function(n) { return p[n]() })("f"))
+  assertEquals(55, (function(n) { return p[n].call(p) })("f"))
+  assertEquals(55, (function(n) { return p[n](15, 20) })("withargs"))
+  assertEquals(55, (function(n) { return p[n].call(p, 13, 21) })("withargs"))
   assertEquals("6655", "66" + p)  // calls p.toString
+
+  var o = Object.create(p, {g: {value: function(x) { return x + 88 }}})
+  assertEquals(55, o.f())
+  assertEquals(55, o["f"]())
+  assertEquals(55, o.f("unused", "arguments"))
+  assertEquals(55, o.f.call(o))
+  assertEquals(55, o.f.call(p))
+  assertEquals(55, o["f"].call(p))
+  assertEquals(55, o[101].call(p))
+  assertEquals(55, o.withargs(45, 5))
+  assertEquals(55, o.withargs.call(p, 11, 22))
+  assertEquals(90, o.g(2))
+  assertEquals(91, o.g.call(o, 3))
+  assertEquals(92, o.g.call(p, 4))
+  assertEquals(55, (function(n) { return o[n]() })("f"))
+  assertEquals(55, (function(n) { return o[n].call(o) })("f"))
+  assertEquals(55, (function(n) { return o[n](15, 20) })("withargs"))
+  assertEquals(55, (function(n) { return o[n].call(o, 13, 21) })("withargs"))
+  assertEquals(93, (function(n) { return o[n](5) })("g"))
+  assertEquals(94, (function(n) { return o[n].call(o, 6) })("g"))
+  assertEquals(95, (function(n) { return o[n].call(p, 7) })("g"))
+  assertEquals("6655", "66" + o)  // calls o.toString
 }
 
 TestGetCall({
@@ -168,10 +294,20 @@
   TestWithProxies(TestGetThrow2, handler)
 }
 
-function TestGetThrow2(handler, create) {
+function TestGetThrow2(create, handler) {
   var p = create(handler)
   assertThrows(function(){ p.a }, "myexn")
   assertThrows(function(){ p["b"] }, "myexn")
+  assertThrows(function(){ p[3] }, "myexn")
+  assertThrows(function(){ (function(n) { p[n] })("c") }, "myexn")
+  assertThrows(function(){ (function(n) { p[n] })(99) }, "myexn")
+
+  var o = Object.create(p, {x: {value: 88}, '4': {value: 89}})
+  assertThrows(function(){ o.a }, "myexn")
+  assertThrows(function(){ o["b"] }, "myexn")
+  assertThrows(function(){ o[3] }, "myexn")
+  assertThrows(function(){ (function(n) { o[n] })("c") }, "myexn")
+  assertThrows(function(){ (function(n) { o[n] })(99) }, "myexn")
 }
 
 TestGetThrow({
@@ -220,11 +356,11 @@
 var key
 var val
 
-function TestSet(handler, create) {
+function TestSet(handler) {
   TestWithProxies(TestSet2, handler)
 }
 
-function TestSet2(handler, create) {
+function TestSet2(create, handler) {
   var p = create(handler)
   assertEquals(42, p.a = 42)
   assertEquals("a", key)
@@ -232,6 +368,16 @@
   assertEquals(43, p["b"] = 43)
   assertEquals("b", key)
   assertEquals(43, val)
+  assertEquals(44, p[77] = 44)
+  assertEquals("77", key)
+  assertEquals(44, val)
+
+  assertEquals(45, (function(n) { return p[n] = 45 })("c"))
+  assertEquals("c", key)
+  assertEquals(45, val)
+  assertEquals(46, (function(n) { return p[n] = 46 })(99))
+  assertEquals("99", key)
+  assertEquals(46, val)
 }
 
 TestSet({
@@ -304,15 +450,17 @@
 }))
 
 
-
-function TestSetThrow(handler, create) {
+function TestSetThrow(handler) {
   TestWithProxies(TestSetThrow2, handler)
 }
 
-function TestSetThrow2(handler, create) {
+function TestSetThrow2(create, handler) {
   var p = create(handler)
   assertThrows(function(){ p.a = 42 }, "myexn")
   assertThrows(function(){ p["b"] = 42 }, "myexn")
+  assertThrows(function(){ p[22] = 42 }, "myexn")
+  assertThrows(function(){ (function(n) { p[n] = 45 })("c") }, "myexn")
+  assertThrows(function(){ (function(n) { p[n] = 46 })(99) }, "myexn")
 }
 
 TestSetThrow({
@@ -424,6 +572,124 @@
 }))
 
 
+var key
+var val
+
+function TestSetForDerived(handler) {
+  TestWithProxies(TestSetForDerived2, handler)
+}
+
+function TestSetForDerived2(create, handler) {
+  var p = create(handler)
+  var o = Object.create(p, {x: {value: 88, writable: true},
+                            '1': {value: 89, writable: true}})
+
+  key = ""
+  assertEquals(48, o.x = 48)
+  assertEquals("", key)  // trap not invoked
+  assertEquals(48, o.x)
+
+  assertEquals(47, o[1] = 47)
+  assertEquals("", key)  // trap not invoked
+  assertEquals(47, o[1])
+
+  assertEquals(49, o.y = 49)
+  assertEquals("y", key)
+  assertEquals(49, o.y)
+
+  assertEquals(50, o[2] = 50)
+  assertEquals("2", key)
+  assertEquals(50, o[2])
+
+  assertEquals(44, o.p_writable = 44)
+  assertEquals("p_writable", key)
+  assertEquals(44, o.p_writable)
+
+  assertEquals(45, o.p_nonwritable = 45)
+  assertEquals("p_nonwritable", key)
+  assertEquals(45, o.p_nonwritable)
+
+  assertEquals(46, o.p_setter = 46)
+  assertEquals("p_setter", key)
+  assertEquals(46, val)  // written to parent
+  assertFalse(Object.prototype.hasOwnProperty.call(o, "p_setter"))
+
+  val = ""
+  assertEquals(47, o.p_nosetter = 47)
+  assertEquals("p_nosetter", key)
+  assertEquals("", val)  // not written at all
+  assertFalse(Object.prototype.hasOwnProperty.call(o, "p_nosetter"));
+
+  key = ""
+  assertThrows(function(){ "use strict"; o.p_nosetter = 50 }, TypeError)
+  assertEquals("p_nosetter", key)
+  assertEquals("", val)  // not written at all
+
+  assertThrows(function(){ o.p_nonconf = 53 }, TypeError)
+  assertEquals("p_nonconf", key)
+
+  assertThrows(function(){ o.p_throw = 51 }, "myexn")
+  assertEquals("p_throw", key)
+
+  assertThrows(function(){ o.p_setterthrow = 52 }, "myexn")
+  assertEquals("p_setterthrow", key)
+}
+
+TestSetForDerived({
+  getPropertyDescriptor: function(k) {
+    key = k;
+    switch (k) {
+      case "p_writable": return {writable: true, configurable: true}
+      case "p_nonwritable": return {writable: false, configurable: true}
+      case "p_setter":return {set: function(x) { val = x }, configurable: true}
+      case "p_nosetter": return {get: function() { return 1 }, configurable: true}
+      case "p_nonconf":return {}
+      case "p_throw": throw "myexn"
+      case "p_setterthrow": return {set: function(x) { throw "myexn" }}
+      default: return undefined
+    }
+  }
+})
+
+
+// Evil proxy-induced side-effects shouldn't crash.
+// TODO(rossberg): proper behaviour isn't really spec'ed yet, so ignore results.
+
+TestWithProxies(function(create) {
+  var calls = 0
+  var handler = {
+    getPropertyDescriptor: function() {
+      ++calls
+      return (calls % 2 == 1)
+        ? {get: function() { return 5 }, configurable: true}
+        : {set: function() { return false }, configurable: true}
+    }
+  }
+  var p = create(handler)
+  var o = Object.create(p)
+  // Make proxy prototype property read-only after CanPut check.
+  try { o.x = 4 } catch (e) { assertInstanceof(e, Error) }
+})
+
+TestWithProxies(function(create) {
+  var handler = {
+    getPropertyDescriptor: function() {
+      Object.defineProperty(o, "x", {get: function() { return 5 }});
+      return {set: function() {}}
+    }
+  }
+  var p = create(handler)
+  var o = Object.create(p)
+  // Make object property read-only after CanPut check.
+  try { o.x = 4 } catch (e) { assertInstanceof(e, Error) }
+})
+
+
+
+// TODO(rossberg): TestSetReject, returning false
+// TODO(rossberg): TestGetProperty, TestSetProperty
+
+
 
 // Property definition (Object.defineProperty and Object.defineProperties).
 
@@ -434,7 +700,7 @@
   TestWithProxies(TestDefine2, handler)
 }
 
-function TestDefine2(handler, create) {
+function TestDefine2(create, handler) {
   var p = create(handler)
   assertEquals(p, Object.defineProperty(p, "a", {value: 44}))
   assertEquals("a", key)
@@ -453,6 +719,12 @@
   assertEquals(46, desc.value)
   assertEquals(false, desc.enumerable)
 
+  assertEquals(p, Object.defineProperty(p, 101, {value: 47, enumerable: false}))
+  assertEquals("101", key)
+  assertEquals(2, Object.getOwnPropertyNames(desc).length)
+  assertEquals(47, desc.value)
+  assertEquals(false, desc.enumerable)
+
   var attributes = {configurable: true, mine: 66, minetoo: 23}
   assertEquals(p, Object.defineProperty(p, "d", attributes))
   assertEquals("d", key)
@@ -474,20 +746,20 @@
   assertEquals("zzz", key)
   assertEquals(0, Object.getOwnPropertyNames(desc).length)
 
-// TODO(rossberg): This test requires for-in on proxies.
-//  var d = create({
-//    get: function(r, k) { return (k === "value") ? 77 : void 0 },
-//    getOwnPropertyNames: function() { return ["value"] }
-//  })
-//  assertEquals(1, Object.getOwnPropertyNames(d).length)
-//  assertEquals(77, d.value)
-//  assertEquals(p, Object.defineProperty(p, "p", d))
-//  assertEquals("p", key)
-//  assertEquals(1, Object.getOwnPropertyNames(desc).length)
-//  assertEquals(77, desc.value)
+  var d = create({
+    get: function(r, k) { return (k === "value") ? 77 : void 0 },
+    getOwnPropertyNames: function() { return ["value"] },
+    enumerate: function() { return ["value"] }
+  })
+  assertEquals(1, Object.getOwnPropertyNames(d).length)
+  assertEquals(77, d.value)
+  assertEquals(p, Object.defineProperty(p, "p", d))
+  assertEquals("p", key)
+  assertEquals(1, Object.getOwnPropertyNames(desc).length)
+  assertEquals(77, desc.value)
 
   var props = {
-    'bla': {},
+    '11': {},
     blub: {get: function() { return true }},
     '': {get value() { return 20 }},
     last: {value: 21, configurable: true, mine: "eyes"}
@@ -524,21 +796,21 @@
   TestWithProxies(TestDefineThrow2, handler)
 }
 
-function TestDefineThrow2(handler, create) {
+function TestDefineThrow2(create, handler) {
   var p = create(handler)
   assertThrows(function(){ Object.defineProperty(p, "a", {value: 44})}, "myexn")
+  assertThrows(function(){ Object.defineProperty(p, 0, {value: 44})}, "myexn")
 
-// TODO(rossberg): These tests require for-in on proxies.
-//  var d1 = create({
-//    get: function(r, k) { throw "myexn" },
-//    getOwnPropertyNames: function() { return ["value"] }
-//  })
-//  assertThrows(function(){ Object.defineProperty(p, "p", d1) }, "myexn")
-//  var d2 = create({
-//    get: function(r, k) { return 77 },
-//    getOwnPropertyNames: function() { throw "myexn" }
-//  })
-//  assertThrows(function(){ Object.defineProperty(p, "p", d2) }, "myexn")
+  var d1 = create({
+    get: function(r, k) { throw "myexn" },
+    getOwnPropertyNames: function() { return ["value"] }
+  })
+  assertThrows(function(){ Object.defineProperty(p, "p", d1) }, "myexn")
+  var d2 = create({
+    get: function(r, k) { return 77 },
+    getOwnPropertyNames: function() { throw "myexn" }
+  })
+  assertThrows(function(){ Object.defineProperty(p, "p", d2) }, "myexn")
 
   var props = {bla: {get value() { throw "otherexn" }}}
   assertThrows(function(){ Object.defineProperties(p, props) }, "otherexn")
@@ -573,12 +845,14 @@
   TestWithProxies(TestDelete2, handler)
 }
 
-function TestDelete2(handler, create) {
+function TestDelete2(create, handler) {
   var p = create(handler)
   assertEquals(true, delete p.a)
   assertEquals("a", key)
   assertEquals(true, delete p["b"])
   assertEquals("b", key)
+  assertEquals(true, delete p[1])
+  assertEquals("1", key)
 
   assertEquals(false, delete p.z1)
   assertEquals("z1", key)
@@ -591,6 +865,8 @@
     assertEquals("c", key)
     assertEquals(true, delete p["d"])
     assertEquals("d", key)
+    assertEquals(true, delete p[2])
+    assertEquals("2", key)
 
     assertThrows(function(){ delete p.z3 }, TypeError)
     assertEquals("z3", key)
@@ -619,15 +895,17 @@
   TestWithProxies(TestDeleteThrow2, handler)
 }
 
-function TestDeleteThrow2(handler, create) {
+function TestDeleteThrow2(create, handler) {
   var p = create(handler)
   assertThrows(function(){ delete p.a }, "myexn")
   assertThrows(function(){ delete p["b"] }, "myexn");
+  assertThrows(function(){ delete p[3] }, "myexn");
 
   (function() {
     "use strict"
     assertThrows(function(){ delete p.c }, "myexn")
     assertThrows(function(){ delete p["d"] }, "myexn")
+    assertThrows(function(){ delete p[4] }, "myexn");
   })()
 }
 
@@ -658,7 +936,7 @@
   TestWithProxies(TestDescriptor2, handler)
 }
 
-function TestDescriptor2(handler, create) {
+function TestDescriptor2(create, handler) {
   var p = create(handler)
   var descs = [
     {configurable: true},
@@ -697,7 +975,7 @@
   TestWithProxies(TestDescriptorThrow2, handler)
 }
 
-function TestDescriptorThrow2(handler, create) {
+function TestDescriptorThrow2(create, handler) {
   var p = create(handler)
   assertThrows(function(){ Object.getOwnPropertyDescriptor(p, "a") }, "myexn")
 }
@@ -721,7 +999,7 @@
   TestWithProxies(TestComparison2, eq)
 }
 
-function TestComparison2(eq, create) {
+function TestComparison2(create, eq) {
   var p1 = create({})
   var p2 = create({})
 
@@ -764,7 +1042,7 @@
   TestWithProxies(TestIn2, handler)
 }
 
-function TestIn2(handler, create) {
+function TestIn2(create, handler) {
   var p = create(handler)
   assertTrue("a" in p)
   assertEquals("a", key)
@@ -778,6 +1056,7 @@
   assertEquals(0, ("zzz" in p) ? 2 : 0)
   assertEquals(2, !("zzz" in p) ? 2 : 0)
 
+  // Test compilation in conditionals.
   if ("b" in p) {
   } else {
     assertTrue(false)
@@ -830,7 +1109,7 @@
 })
 
 TestIn({
-  get: undefined,
+  has: undefined,
   getPropertyDescriptor: function(k) {
     key = k; return k < "z" ? {value: 42} : void 0
   }
@@ -847,9 +1126,10 @@
   TestWithProxies(TestInThrow2, handler)
 }
 
-function TestInThrow2(handler, create) {
+function TestInThrow2(create, handler) {
   var p = create(handler)
   assertThrows(function(){ return "a" in o }, "myexn")
+  assertThrows(function(){ return 99 in o }, "myexn")
   assertThrows(function(){ return !("a" in o) }, "myexn")
   assertThrows(function(){ return ("a" in o) ? 2 : 3 }, "myexn")
   assertThrows(function(){ if ("b" in o) {} }, "myexn")
@@ -876,7 +1156,7 @@
 })
 
 TestInThrow({
-  get: undefined,
+  has: undefined,
   getPropertyDescriptor: function(k) { throw "myexn" }
 })
 
@@ -891,6 +1171,158 @@
 }))
 
 
+function TestInForDerived(handler) {
+  TestWithProxies(TestInForDerived2, handler)
+}
+
+function TestInForDerived2(create, handler) {
+  var p = create(handler)
+  var o = Object.create(p)
+
+  assertTrue("a" in o)
+  assertEquals("a", key)
+  assertTrue(99 in o)
+  assertEquals("99", key)
+  assertFalse("z" in o)
+  assertEquals("z", key)
+
+  assertEquals(2, ("a" in o) ? 2 : 0)
+  assertEquals(0, !("a" in o) ? 2 : 0)
+  assertEquals(0, ("zzz" in o) ? 2 : 0)
+  assertEquals(2, !("zzz" in o) ? 2 : 0)
+
+  if ("b" in o) {
+  } else {
+    assertTrue(false)
+  }
+  assertEquals("b", key)
+
+  if ("zz" in o) {
+    assertTrue(false)
+  }
+  assertEquals("zz", key)
+
+  if (!("c" in o)) {
+    assertTrue(false)
+  }
+  assertEquals("c", key)
+
+  if (!("zzz" in o)) {
+  } else {
+    assertTrue(false)
+  }
+  assertEquals("zzz", key)
+}
+
+TestInForDerived({
+  getPropertyDescriptor: function(k) {
+    key = k; return k < "z" ? {value: 42, configurable: true} : void 0
+  }
+})
+
+TestInForDerived({
+  getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
+  getPropertyDescriptor2: function(k) {
+    key = k; return k < "z" ? {value: 42, configurable: true} : void 0
+  }
+})
+
+TestInForDerived({
+  getPropertyDescriptor: function(k) {
+    key = k;
+    return k < "z" ? {get value() { return 42 }, configurable: true} : void 0
+  }
+})
+
+/* TODO(rossberg): this will work once we implement the newest proposal
+ * regarding default traps for getPropertyDescriptor.
+TestInForDerived({
+  getOwnPropertyDescriptor: function(k) {
+    key = k; return k < "z" ? {value: 42, configurable: true} : void 0
+  }
+})
+
+TestInForDerived({
+  getOwnPropertyDescriptor: function(k) {
+    return this.getOwnPropertyDescriptor2(k)
+  },
+  getOwnPropertyDescriptor2: function(k) {
+    key = k; return k < "z" ? {value: 42, configurable: true} : void 0
+  }
+})
+
+TestInForDerived({
+  getOwnPropertyDescriptor: function(k) {
+    key = k;
+    return k < "z" ? {get value() { return 42 }, configurable: true} : void 0
+  }
+})
+*/
+
+TestInForDerived(Proxy.create({
+  get: function(pr, pk) {
+    return function(k) {
+      key = k; return k < "z" ? {value: 42, configurable: true} : void 0
+    }
+  }
+}))
+
+
+
+// Property descriptor conversion.
+
+var descget
+
+function TestDescriptorGetOrder(handler) {
+  var p = Proxy.create(handler)
+  var o = Object.create(p, {b: {value: 0}})
+  TestDescriptorGetOrder2(function(n) { return p[n] }, "vV")
+  TestDescriptorGetOrder2(function(n) { return n in p }, "")
+  TestDescriptorGetOrder2(function(n) { return o[n] }, "vV")
+  TestDescriptorGetOrder2(function(n) { return n in o }, "eEcCvVwWgs")
+}
+
+function TestDescriptorGetOrder2(f, access) {
+  descget = ""
+  assertTrue(f("a"))
+  assertEquals(access, descget)
+  descget = ""
+  assertTrue(f(99))
+  assertEquals(access, descget)
+  descget = ""
+  assertFalse(!!f("z"))
+  assertEquals("", descget)
+}
+
+TestDescriptorGetOrder({
+  getPropertyDescriptor: function(k) {
+    if (k >= "z") return void 0
+    // Return a proxy as property descriptor, so that we can log accesses.
+    return Proxy.create({
+      get: function(r, attr) {
+        descget += attr[0].toUpperCase()
+        return true
+      },
+      has: function(attr) {
+        descget += attr[0]
+        switch (attr) {
+          case "writable":
+          case "enumerable":
+          case "configurable":
+          case "value":
+            return true
+          case "get":
+          case "set":
+            return false
+          default:
+            assertUnreachable()
+        }
+      }
+    })
+  }
+})
+
+
 
 // Own Properties (Object.prototype.hasOwnProperty).
 
@@ -900,7 +1332,7 @@
   TestWithProxies(TestHasOwn2, handler)
 }
 
-function TestHasOwn2(handler, create) {
+function TestHasOwn2(create, handler) {
   var p = create(handler)
   assertTrue(Object.prototype.hasOwnProperty.call(p, "a"))
   assertEquals("a", key)
@@ -958,7 +1390,7 @@
   TestWithProxies(TestHasOwnThrow2, handler)
 }
 
-function TestHasOwnThrow2(handler, create) {
+function TestHasOwnThrow2(create, handler) {
   var p = create(handler)
   assertThrows(function(){ Object.prototype.hasOwnProperty.call(p, "a")},
     "myexn")
@@ -1005,84 +1437,173 @@
 
 // Instanceof (instanceof)
 
-function TestInstanceof() {
-  var o = {}
+function TestProxyInstanceof() {
+  var o1 = {}
   var p1 = Proxy.create({})
-  var p2 = Proxy.create({}, o)
+  var p2 = Proxy.create({}, o1)
   var p3 = Proxy.create({}, p2)
+  var o2 = Object.create(p2)
 
   var f0 = function() {}
-  f0.prototype = o
+  f0.prototype = o1
   var f1 = function() {}
   f1.prototype = p1
   var f2 = function() {}
   f2.prototype = p2
+  var f3 = function() {}
+  f3.prototype = o2
 
-  assertTrue(o instanceof Object)
-  assertFalse(o instanceof f0)
-  assertFalse(o instanceof f1)
-  assertFalse(o instanceof f2)
+  assertTrue(o1 instanceof Object)
+  assertFalse(o1 instanceof f0)
+  assertFalse(o1 instanceof f1)
+  assertFalse(o1 instanceof f2)
+  assertFalse(o1 instanceof f3)
   assertFalse(p1 instanceof Object)
   assertFalse(p1 instanceof f0)
   assertFalse(p1 instanceof f1)
   assertFalse(p1 instanceof f2)
+  assertFalse(p1 instanceof f3)
   assertTrue(p2 instanceof Object)
   assertTrue(p2 instanceof f0)
   assertFalse(p2 instanceof f1)
   assertFalse(p2 instanceof f2)
+  assertFalse(p2 instanceof f3)
   assertTrue(p3 instanceof Object)
   assertTrue(p3 instanceof f0)
   assertFalse(p3 instanceof f1)
   assertTrue(p3 instanceof f2)
+  assertFalse(p3 instanceof f3)
+  assertTrue(o2 instanceof Object)
+  assertTrue(o2 instanceof f0)
+  assertFalse(o2 instanceof f1)
+  assertTrue(o2 instanceof f2)
+  assertFalse(o2 instanceof f3)
 
   var f = Proxy.createFunction({}, function() {})
   assertTrue(f instanceof Function)
 }
 
-TestInstanceof()
+TestProxyInstanceof()
+
+
+function TestInstanceofProxy() {
+  var o0 = Object.create(null)
+  var o1 = {}
+  var o2 = Object.create(o0)
+  var o3 = Object.create(o1)
+  var o4 = Object.create(o2)
+  var o5 = Object.create(o3)
+
+  function handler(o) { return {get: function() { return o } } }
+  var f0 = Proxy.createFunction(handler(o0), function() {})
+  var f1 = Proxy.createFunction(handler(o1), function() {})
+  var f2 = Proxy.createFunction(handler(o2), function() {})
+  var f3 = Proxy.createFunction(handler(o3), function() {})
+  var f4 = Proxy.createFunction(handler(o4), function() {})
+  var f5 = Proxy.createFunction(handler(o4), function() {})
+
+  assertFalse(null instanceof f0)
+  assertFalse(o0 instanceof f0)
+  assertFalse(o0 instanceof f1)
+  assertFalse(o0 instanceof f2)
+  assertFalse(o0 instanceof f3)
+  assertFalse(o0 instanceof f4)
+  assertFalse(o0 instanceof f5)
+  assertFalse(o1 instanceof f0)
+  assertFalse(o1 instanceof f1)
+  assertFalse(o1 instanceof f2)
+  assertFalse(o1 instanceof f3)
+  assertFalse(o1 instanceof f4)
+  assertFalse(o1 instanceof f5)
+  assertTrue(o2 instanceof f0)
+  assertFalse(o2 instanceof f1)
+  assertFalse(o2 instanceof f2)
+  assertFalse(o2 instanceof f3)
+  assertFalse(o2 instanceof f4)
+  assertFalse(o2 instanceof f5)
+  assertFalse(o3 instanceof f0)
+  assertTrue(o3 instanceof f1)
+  assertFalse(o3 instanceof f2)
+  assertFalse(o3 instanceof f3)
+  assertFalse(o3 instanceof f4)
+  assertFalse(o3 instanceof f5)
+  assertTrue(o4 instanceof f0)
+  assertFalse(o4 instanceof f1)
+  assertTrue(o4 instanceof f2)
+  assertFalse(o4 instanceof f3)
+  assertFalse(o4 instanceof f4)
+  assertFalse(o4 instanceof f5)
+  assertFalse(o5 instanceof f0)
+  assertTrue(o5 instanceof f1)
+  assertFalse(o5 instanceof f2)
+  assertTrue(o5 instanceof f3)
+  assertFalse(o5 instanceof f4)
+  assertFalse(o5 instanceof f5)
+
+  var f = Proxy.createFunction({}, function() {})
+  var ff = Proxy.createFunction(handler(Function), function() {})
+  assertTrue(f instanceof Function)
+  assertFalse(f instanceof ff)
+}
+
+TestInstanceofProxy()
 
 
 
 // Prototype (Object.getPrototypeOf, Object.prototype.isPrototypeOf).
 
 function TestPrototype() {
-  var o = {}
+  var o1 = {}
   var p1 = Proxy.create({})
-  var p2 = Proxy.create({}, o)
+  var p2 = Proxy.create({}, o1)
   var p3 = Proxy.create({}, p2)
-  var p4 = Proxy.create({}, 666)
+  var p4 = Proxy.create({}, null)
+  var o2 = Object.create(p3)
 
-  assertSame(Object.getPrototypeOf(o), Object.prototype)
+  assertSame(Object.getPrototypeOf(o1), Object.prototype)
   assertSame(Object.getPrototypeOf(p1), null)
-  assertSame(Object.getPrototypeOf(p2), o)
+  assertSame(Object.getPrototypeOf(p2), o1)
   assertSame(Object.getPrototypeOf(p3), p2)
   assertSame(Object.getPrototypeOf(p4), null)
+  assertSame(Object.getPrototypeOf(o2), p3)
 
-  assertTrue(Object.prototype.isPrototypeOf(o))
+  assertTrue(Object.prototype.isPrototypeOf(o1))
   assertFalse(Object.prototype.isPrototypeOf(p1))
   assertTrue(Object.prototype.isPrototypeOf(p2))
   assertTrue(Object.prototype.isPrototypeOf(p3))
   assertFalse(Object.prototype.isPrototypeOf(p4))
-  assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, o))
+  assertTrue(Object.prototype.isPrototypeOf(o2))
+  assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, o1))
   assertFalse(Object.prototype.isPrototypeOf.call(Object.prototype, p1))
   assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, p2))
   assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, p3))
   assertFalse(Object.prototype.isPrototypeOf.call(Object.prototype, p4))
-  assertFalse(Object.prototype.isPrototypeOf.call(o, o))
-  assertFalse(Object.prototype.isPrototypeOf.call(o, p1))
-  assertTrue(Object.prototype.isPrototypeOf.call(o, p2))
-  assertTrue(Object.prototype.isPrototypeOf.call(o, p3))
-  assertFalse(Object.prototype.isPrototypeOf.call(o, p4))
+  assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, o2))
+  assertFalse(Object.prototype.isPrototypeOf.call(o1, o1))
+  assertFalse(Object.prototype.isPrototypeOf.call(o1, p1))
+  assertTrue(Object.prototype.isPrototypeOf.call(o1, p2))
+  assertTrue(Object.prototype.isPrototypeOf.call(o1, p3))
+  assertFalse(Object.prototype.isPrototypeOf.call(o1, p4))
+  assertTrue(Object.prototype.isPrototypeOf.call(o1, o2))
   assertFalse(Object.prototype.isPrototypeOf.call(p1, p1))
-  assertFalse(Object.prototype.isPrototypeOf.call(p1, o))
+  assertFalse(Object.prototype.isPrototypeOf.call(p1, o1))
   assertFalse(Object.prototype.isPrototypeOf.call(p1, p2))
   assertFalse(Object.prototype.isPrototypeOf.call(p1, p3))
   assertFalse(Object.prototype.isPrototypeOf.call(p1, p4))
+  assertFalse(Object.prototype.isPrototypeOf.call(p1, o2))
   assertFalse(Object.prototype.isPrototypeOf.call(p2, p1))
   assertFalse(Object.prototype.isPrototypeOf.call(p2, p2))
   assertTrue(Object.prototype.isPrototypeOf.call(p2, p3))
   assertFalse(Object.prototype.isPrototypeOf.call(p2, p4))
+  assertTrue(Object.prototype.isPrototypeOf.call(p2, o2))
   assertFalse(Object.prototype.isPrototypeOf.call(p3, p2))
+  assertTrue(Object.prototype.isPrototypeOf.call(p3, o2))
+  assertFalse(Object.prototype.isPrototypeOf.call(o2, o1))
+  assertFalse(Object.prototype.isPrototypeOf.call(o2, p1))
+  assertFalse(Object.prototype.isPrototypeOf.call(o2, p2))
+  assertFalse(Object.prototype.isPrototypeOf.call(o2, p3))
+  assertFalse(Object.prototype.isPrototypeOf.call(o2, p4))
+  assertFalse(Object.prototype.isPrototypeOf.call(o2, o2))
 
   var f = Proxy.createFunction({}, function() {})
   assertSame(Object.getPrototypeOf(f), Function.prototype)
@@ -1097,12 +1618,12 @@
 // Property names (Object.getOwnPropertyNames, Object.keys).
 
 function TestPropertyNames(names, handler) {
-  TestWithProxies(TestPropertyNames2, [names, handler])
+  TestWithProxies(TestPropertyNames2, handler, names)
 }
 
-function TestPropertyNames2(names_handler, create) {
-  var p = create(names_handler[1])
-  assertArrayEquals(names_handler[0], Object.getOwnPropertyNames(p))
+function TestPropertyNames2(create, handler, names) {
+  var p = create(handler)
+  assertArrayEquals(names, Object.getOwnPropertyNames(p))
 }
 
 TestPropertyNames([], {
@@ -1129,7 +1650,7 @@
   TestWithProxies(TestPropertyNamesThrow2, handler)
 }
 
-function TestPropertyNamesThrow2(handler, create) {
+function TestPropertyNamesThrow2(create, handler) {
   var p = create(handler)
   assertThrows(function(){ Object.getOwnPropertyNames(p) }, "myexn")
 }
@@ -1145,12 +1666,12 @@
 
 
 function TestKeys(names, handler) {
-  TestWithProxies(TestKeys2, [names, handler])
+  TestWithProxies(TestKeys2, handler, names)
 }
 
-function TestKeys2(names_handler, create) {
-  var p = create(names_handler[1])
-  assertArrayEquals(names_handler[0], Object.keys(p))
+function TestKeys2(create, handler, names) {
+  var p = create(handler)
+  assertArrayEquals(names, Object.keys(p))
 }
 
 TestKeys([], {
@@ -1174,7 +1695,9 @@
 
 TestKeys(["a", "0"], {
   getOwnPropertyNames: function() { return ["a", 23, "zz", "", 0] },
-  getOwnPropertyDescriptor: function(k) { return {enumerable: k.length == 1} }
+  getOwnPropertyDescriptor: function(k) {
+    return k == "" ? undefined : {enumerable: k.length == 1}
+  }
 })
 
 TestKeys(["23", "zz", ""], {
@@ -1188,10 +1711,12 @@
 
 TestKeys(["a", "b", "c", "5"], {
   get getOwnPropertyNames() {
-    return function() { return ["0", 4, "a", "b", "c", 5] }
+    return function() { return ["0", 4, "a", "b", "c", 5, "ety"] }
   },
   get getOwnPropertyDescriptor() {
-    return function(k) { return {enumerable: k >= "44"} }
+    return function(k) {
+      return k == "ety" ? undefined : {enumerable: k >= "44"}
+    }
   }
 })
 
@@ -1207,7 +1732,7 @@
   TestWithProxies(TestKeysThrow2, handler)
 }
 
-function TestKeysThrow2(handler, create) {
+function TestKeysThrow2(create, handler) {
   var p = create(handler)
   assertThrows(function(){ Object.keys(p) }, "myexn")
 }
@@ -1267,7 +1792,6 @@
 // Fixing (Object.freeze, Object.seal, Object.preventExtensions,
 //         Object.isFrozen, Object.isSealed, Object.isExtensible)
 
-// TODO(rossberg): use TestWithProxies to include funciton proxies
 function TestFix(names, handler) {
   var proto = {p: 77}
   var assertFixing = function(o, s, f, e) {
@@ -1314,19 +1838,27 @@
                     Object.keys(p3).sort())
   assertEquals(proto, Object.getPrototypeOf(p3))
   assertEquals(77, p3.p)
+
+  var p = Proxy.create(handler, proto)
+  var o = Object.create(p)
+  assertFixing(p, false, false, true)
+  assertFixing(o, false, false, true)
+  Object.freeze(o)
+  assertFixing(p, false, false, true)
+  assertFixing(o, true, true, false)
 }
 
 TestFix([], {
   fix: function() { return {} }
 })
 
-TestFix(["a", "b", "c", "d", "zz"], {
+TestFix(["a", "b", "c", "3", "zz"], {
   fix: function() {
     return {
       a: {value: "a", writable: true, configurable: false, enumerable: true},
       b: {value: 33, writable: false, configurable: false, enumerable: true},
       c: {value: 0, writable: true, configurable: true, enumerable: true},
-      d: {value: true, writable: false, configurable: true, enumerable: true},
+      '3': {value: true, writable: false, configurable: true, enumerable: true},
       zz: {value: 0, enumerable: false}
     }
   }
@@ -1377,8 +1909,8 @@
   TestWithProxies(TestFixThrow2, handler)
 }
 
-function TestFixThrow2(handler) {
-  var p = Proxy.create(handler, {})
+function TestFixThrow2(create, handler) {
+  var p = create(handler, {})
   assertThrows(function(){ Object.seal(p) }, "myexn")
   assertThrows(function(){ Object.freeze(p) }, "myexn")
   assertThrows(function(){ Object.preventExtensions(p) }, "myexn")
@@ -1404,6 +1936,135 @@
 })
 
 
+// Freeze a proxy in the middle of operations on it.
+// TODO(rossberg): actual behaviour not specified consistently at the moment,
+// just make sure that we do not crash.
+function TestReentrantFix(f) {
+  TestWithProxies(f, Object.freeze)
+  TestWithProxies(f, Object.seal)
+  TestWithProxies(f, Object.preventExtensions)
+}
+
+TestReentrantFix(function(create, freeze) {
+  var handler = {
+    get get() { freeze(p); return undefined },
+    fix: function() { return {} }
+  }
+  var p = create(handler)
+  // Freeze while getting get trap.
+  try { p.x } catch (e) { assertInstanceof(e, Error) }
+})
+
+TestReentrantFix(function(create, freeze) {
+  var handler = {
+    get: function() { freeze(p); return 3 },
+    fix: function() { return {} }
+  }
+  var p = create(handler)
+  // Freeze while executing get trap.
+  try { p.x } catch (e) { assertInstanceof(e, Error) }
+})
+
+TestReentrantFix(function(create, freeze) {
+  var handler = {
+    getPropertyDescriptor: function() { freeze(p); return undefined },
+    fix: function() { return {} }
+  }
+  var p = create(handler)
+  // Freeze while executing default get trap.
+  try { p.x } catch (e) { assertInstanceof(e, Error) }
+})
+
+TestReentrantFix(function(create, freeze) {
+  var handler = {
+    getPropertyDescriptor: function() { freeze(p); return {get: function(){}} },
+    fix: function() { return {} }
+  }
+  var p = create(handler)
+  var o = Object.create(p)
+  // Freeze while getting a property from prototype.
+  try { o.x } catch (e) { assertInstanceof(e, Error) }
+})
+
+TestReentrantFix(function(create, freeze) {
+  var handler = {
+    get set() { freeze(p); return undefined },
+    fix: function() { return {} }
+  }
+  var p = create(handler)
+  // Freeze while getting set trap.
+  try { p.x = 4 } catch (e) { assertInstanceof(e, Error) }
+})
+
+TestReentrantFix(function(create, freeze) {
+  var handler = {
+    set: function() { freeze(p); return true },
+    fix: function() { return {} }
+  }
+  var p = create(handler)
+  // Freeze while executing set trap.
+  try { p.x = 4 } catch (e) { assertInstanceof(e, Error) }
+})
+
+TestReentrantFix(function(create, freeze) {
+  var handler = {
+    getOwnPropertyDescriptor: function() { freeze(p); return undefined },
+    fix: function() { return {} }
+  }
+  var p = create(handler)
+  // Freeze while executing default set trap.
+  try { p.x } catch (e) { assertInstanceof(e, Error) }
+})
+
+TestReentrantFix(function(create, freeze) {
+  var handler = {
+    getPropertyDescriptor: function() { freeze(p); return {set: function(){}} },
+    fix: function() { return {} }
+  }
+  var p = create(handler)
+  var o = Object.create(p)
+  // Freeze while setting a property in prototype, dropping the property!
+  try { o.x = 4 } catch (e) { assertInstanceof(e, Error) }
+})
+
+TestReentrantFix(function(create, freeze) {
+  var handler = {
+    getPropertyDescriptor: function() { freeze(p); return {set: function(){}} },
+    fix: function() { return {x: {get: function(){}}} }
+  }
+  var p = create(handler)
+  var o = Object.create(p)
+  // Freeze while setting a property in prototype, making it read-only!
+  try { o.x = 4 } catch (e) { assertInstanceof(e, Error) }
+})
+
+TestReentrantFix(function(create, freeze) {
+  var handler = {
+    get fix() { freeze(p); return function(){} }
+  }
+  var p = create(handler)
+  // Freeze while getting fix trap.
+  try { Object.freeze(p) } catch (e) { assertInstanceof(e, Error) }
+  p = create(handler)
+  try { Object.seal(p) } catch (e) { assertInstanceof(e, Error) }
+  p = create(handler)
+  try { Object.preventExtensions(p) } catch (e) { assertInstanceof(e, Error) }
+})
+
+TestReentrantFix(function(create, freeze) {
+  var handler = {
+    fix: function() { freeze(p); return {} }
+  }
+  var p = create(handler)
+  // Freeze while executing fix trap.
+  try { Object.freeze(p) } catch (e) { assertInstanceof(e, Error) }
+  p = create(handler)
+  try { Object.seal(p) } catch (e) { assertInstanceof(e, Error) }
+  p = create(handler)
+  try { Object.preventExtensions(p) } catch (e) { assertInstanceof(e, Error) }
+})
+
+
 
 // String conversion (Object.prototype.toString,
 //                    Object.prototype.toLocaleString,
@@ -1426,6 +2087,13 @@
   assertEquals("my_proxy", Object.prototype.toLocaleString.call(f))
   assertEquals("toString", key)
   assertDoesNotThrow(function(){ Function.prototype.toString.call(f) })
+
+  var o = Object.create(p)
+  key = ""
+  assertEquals("[object Object]", Object.prototype.toString.call(o))
+  assertEquals("", key)
+  assertEquals("my_proxy", Object.prototype.toLocaleString.call(o))
+  assertEquals("toString", key)
 }
 
 TestToString({
@@ -1452,6 +2120,10 @@
   var f = Proxy.createFunction(handler, function() {})
   assertEquals("[object Function]", Object.prototype.toString.call(f))
   assertThrows(function(){ Object.prototype.toLocaleString.call(f) }, "myexn")
+
+  var o = Object.create(p)
+  assertEquals("[object Object]", Object.prototype.toString.call(o))
+  assertThrows(function(){ Object.prototype.toLocaleString.call(o) }, "myexn")
 }
 
 TestToStringThrow({
@@ -1485,7 +2157,7 @@
   TestWithProxies(TestValueOf2, handler)
 }
 
-function TestValueOf2(handler, create) {
+function TestValueOf2(create, handler) {
   var p = create(handler)
   assertSame(p, Object.prototype.valueOf.call(p))
 }
@@ -1502,7 +2174,7 @@
   TestWithProxies(TestIsEnumerable2, handler)
 }
 
-function TestIsEnumerable2(handler, create) {
+function TestIsEnumerable2(create, handler) {
   var p = create(handler)
   assertTrue(Object.prototype.propertyIsEnumerable.call(p, "a"))
   assertEquals("a", key)
@@ -1510,6 +2182,11 @@
   assertEquals("2", key)
   assertFalse(Object.prototype.propertyIsEnumerable.call(p, "z"))
   assertEquals("z", key)
+
+  var o = Object.create(p)
+  key = ""
+  assertFalse(Object.prototype.propertyIsEnumerable.call(o, "a"))
+  assertEquals("", key)  // trap not invoked
 }
 
 TestIsEnumerable({
@@ -1546,7 +2223,7 @@
   TestWithProxies(TestIsEnumerableThrow2, handler)
 }
 
-function TestIsEnumerableThrow2(handler, create) {
+function TestIsEnumerableThrow2(create, handler) {
   var p = create(handler)
   assertThrows(function(){ Object.prototype.propertyIsEnumerable.call(p, "a") },
     "myexn")
@@ -1580,103 +2257,3 @@
     return function(k) { throw "myexn" }
   }
 }))
-
-
-
-// Calling (call, Function.prototype.call, Function.prototype.apply,
-//          Function.prototype.bind).
-
-var global = this
-var receiver
-
-function TestCall(isStrict, callTrap) {
-  assertEquals(42, callTrap(5, 37))
-// TODO(rossberg): unrelated bug: this does not succeed for optimized code.
-// assertEquals(isStrict ? undefined : global, receiver)
-
-  var f = Proxy.createFunction({fix: function() { return {} }}, callTrap)
-  receiver = 333
-  assertEquals(42, f(11, 31))
-  assertEquals(isStrict ? undefined : global, receiver)
-  var o = {}
-  assertEquals(42, Function.prototype.call.call(f, o, 20, 22))
-  assertEquals(o, receiver)
-  assertEquals(43, Function.prototype.call.call(f, null, 20, 23))
-  assertEquals(isStrict ? null : global, receiver)
-  assertEquals(44, Function.prototype.call.call(f, 2, 21, 23))
-  assertEquals(2, receiver.valueOf())
-  receiver = 333
-  assertEquals(32, Function.prototype.apply.call(f, o, [17, 15]))
-  assertEquals(o, receiver)
-  var ff = Function.prototype.bind.call(f, o, 12)
-  receiver = 333
-  assertEquals(42, ff(30))
-  assertEquals(o, receiver)
-  receiver = 333
-  assertEquals(32, Function.prototype.apply.call(ff, {}, [20]))
-  assertEquals(o, receiver)
-
-  Object.freeze(f)
-  receiver = 333
-  assertEquals(42, f(11, 31))
-// TODO(rossberg): unrelated bug: this does not succeed for optimized code.
-// assertEquals(isStrict ? undefined : global, receiver)
-  receiver = 333
-  assertEquals(42, Function.prototype.call.call(f, o, 20, 22))
-  assertEquals(o, receiver)
-  receiver = 333
-  assertEquals(32, Function.prototype.apply.call(f, o, [17, 15]))
-  assertEquals(o, receiver)
-  receiver = 333
-  assertEquals(42, ff(30))
-  assertEquals(o, receiver)
-  receiver = 333
-  assertEquals(32, Function.prototype.apply.call(ff, {}, [20]))
-  assertEquals(o, receiver)
-}
-
-TestCall(false, function(x, y) {
-  receiver = this; return x + y
-})
-
-TestCall(true, function(x, y) {
-  "use strict";
-  receiver = this; return x + y
-})
-
-TestCall(false, Proxy.createFunction({}, function(x, y) {
-  receiver = this; return x + y
-}))
-
-TestCall(true, Proxy.createFunction({}, function(x, y) {
-  "use strict";
-  receiver = this; return x + y
-}))
-
-var p = Proxy.createFunction({fix: function() {return {}}}, function(x, y) {
-  receiver = this; return x + y
-})
-TestCall(false, p)
-Object.freeze(p)
-TestCall(false, p)
-
-
-function TestCallThrow(callTrap) {
-  var f = Proxy.createFunction({fix: function() {return {}}}, callTrap)
-  assertThrows(function(){ f(11) }, "myexn")
-  assertThrows(function(){ Function.prototype.call.call(f, {}, 2) }, "myexn")
-  assertThrows(function(){ Function.prototype.apply.call(f, {}, [1]) }, "myexn")
-
-  Object.freeze(f)
-  assertThrows(function(){ f(11) }, "myexn")
-  assertThrows(function(){ Function.prototype.call.call(f, {}, 2) }, "myexn")
-  assertThrows(function(){ Function.prototype.apply.call(f, {}, [1]) }, "myexn")
-}
-
-TestCallThrow(function() { throw "myexn" })
-TestCallThrow(Proxy.createFunction({}, function() { throw "myexn" }))
-
-var p = Proxy.createFunction(
-  {fix: function() {return {}}}, function() { throw "myexn" })
-Object.freeze(p)
-TestCallThrow(p)
diff --git a/test/mjsunit/harmony/weakmaps.js b/test/mjsunit/harmony/weakmaps.js
deleted file mode 100644
index 7b5dcaf..0000000
--- a/test/mjsunit/harmony/weakmaps.js
+++ /dev/null
@@ -1,167 +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: --harmony-weakmaps --expose-gc
-
-
-// Test valid getter and setter calls
-var m = new WeakMap;
-assertDoesNotThrow(function () { m.get(new Object) });
-assertDoesNotThrow(function () { m.set(new Object) });
-assertDoesNotThrow(function () { m.has(new Object) });
-assertDoesNotThrow(function () { m.delete(new Object) });
-
-
-// Test invalid getter and setter calls
-var m = new WeakMap;
-assertThrows(function () { m.get(undefined) }, TypeError);
-assertThrows(function () { m.set(undefined, 0) }, TypeError);
-assertThrows(function () { m.get(0) }, TypeError);
-assertThrows(function () { m.set(0, 0) }, TypeError);
-assertThrows(function () { m.get('a-key') }, TypeError);
-assertThrows(function () { m.set('a-key', 0) }, TypeError);
-
-
-// Test expected mapping behavior
-var m = new WeakMap;
-function TestMapping(map, key, value) {
-  map.set(key, value);
-  assertSame(value, map.get(key));
-}
-TestMapping(m, new Object, 23);
-TestMapping(m, new Object, 'the-value');
-TestMapping(m, new Object, new Object);
-
-
-// Test expected querying behavior
-var m = new WeakMap;
-var key = new Object;
-TestMapping(m, key, 'to-be-present');
-assertTrue(m.has(key));
-assertFalse(m.has(new Object));
-TestMapping(m, key, undefined);
-assertFalse(m.has(key));
-assertFalse(m.has(new Object));
-
-
-// Test expected deletion behavior
-var m = new WeakMap;
-var key = new Object;
-TestMapping(m, key, 'to-be-deleted');
-assertTrue(m.delete(key));
-assertFalse(m.delete(key));
-assertFalse(m.delete(new Object));
-assertSame(m.get(key), undefined);
-
-
-// Test GC of map with entry
-var m = new WeakMap;
-var key = new Object;
-m.set(key, 'not-collected');
-gc();
-assertSame('not-collected', m.get(key));
-
-
-// Test GC of map with chained entries
-var m = new WeakMap;
-var head = new Object;
-for (key = head, i = 0; i < 10; i++, key = m.get(key)) {
-  m.set(key, new Object);
-}
-gc();
-var count = 0;
-for (key = head; key != undefined; key = m.get(key)) {
-  count++;
-}
-assertEquals(11, count);
-
-
-// Test property attribute [[Enumerable]]
-var m = new WeakMap;
-function props(x) {
-  var array = [];
-  for (var p in x) array.push(p);
-  return array.sort();
-}
-assertArrayEquals([], props(WeakMap));
-assertArrayEquals([], props(WeakMap.prototype));
-assertArrayEquals([], props(m));
-
-
-// Test arbitrary properties on weak maps
-var m = new WeakMap;
-function TestProperty(map, property, value) {
-  map[property] = value;
-  assertEquals(value, map[property]);
-}
-for (i = 0; i < 20; i++) {
-  TestProperty(m, i, 'val' + i);
-  TestProperty(m, 'foo' + i, 'bar' + i);
-}
-TestMapping(m, new Object, 'foobar');
-
-
-// Test direct constructor call
-var m = WeakMap();
-assertTrue(m instanceof WeakMap);
-
-
-// Test some common JavaScript idioms
-var m = new WeakMap;
-assertTrue(m instanceof WeakMap);
-assertTrue(WeakMap.prototype.set instanceof Function)
-assertTrue(WeakMap.prototype.get instanceof Function)
-assertTrue(WeakMap.prototype.has instanceof Function)
-assertTrue(WeakMap.prototype.delete instanceof Function)
-
-
-// Regression test for WeakMap prototype.
-assertTrue(WeakMap.prototype.constructor === WeakMap)
-assertTrue(Object.getPrototypeOf(WeakMap.prototype) === Object.prototype)
-
-
-// Regression test for issue 1617: The prototype of the WeakMap constructor
-// needs to be unique (i.e. different from the one of the Object constructor).
-assertFalse(WeakMap.prototype === Object.prototype);
-var o = Object.create({});
-assertFalse("get" in o);
-assertFalse("set" in o);
-assertEquals(undefined, o.get);
-assertEquals(undefined, o.set);
-var o = Object.create({}, { myValue: {
-  value: 10,
-  enumerable: false,
-  configurable: true,
-  writable: true
-}});
-assertEquals(10, o.myValue);
-
-
-// Stress Test
-// There is a proposed stress-test available at the es-discuss mailing list
-// which cannot be reasonably automated.  Check it out by hand if you like:
-// https://mail.mozilla.org/pipermail/es-discuss/2011-May/014096.html
diff --git a/test/mjsunit/mjsunit.js b/test/mjsunit/mjsunit.js
index faa5a43..6f6e323 100644
--- a/test/mjsunit/mjsunit.js
+++ b/test/mjsunit/mjsunit.js
@@ -223,7 +223,7 @@
   assertSame = function assertSame(expected, found, name_opt) {
     if (found === expected) {
       if (expected !== 0 || (1 / expected) == (1 / found)) return;
-    } else if (isNaN(expected) && isNaN(found)) {
+    } else if ((expected !== expected) && (found !== found)) {
       return;
     }
     fail(PrettyPrint(expected), found, name_opt);
diff --git a/test/mjsunit/mjsunit.status b/test/mjsunit/mjsunit.status
index bae09b4..cdac99b 100644
--- a/test/mjsunit/mjsunit.status
+++ b/test/mjsunit/mjsunit.status
@@ -34,9 +34,13 @@
 # Fails.
 regress/regress-1119: FAIL
 
-#############################################################################
-# Fails due to r10102 which reverts precise stepping on the 3.6 branch.
-debug-step-2: FAIL
+##############################################################################
+
+# Issue 1845: http://code.google.com/p/v8/issues/detail?id=1845
+harmony/proxies-example-membrane: SKIP
+
+# NewGC: BUG(1719) slow to collect arrays over several contexts.
+regress/regress-524: SKIP
 
 ##############################################################################
 # Too slow in debug mode with --stress-opt
@@ -64,7 +68,6 @@
 debug-liveedit-check-stack: SKIP
 debug-liveedit-patch-positions-replace: SKIP
 
-
 ##############################################################################
 [ $arch == arm ]
 
diff --git a/test/mjsunit/object-define-properties.js b/test/mjsunit/object-define-properties.js
index 128df69..6d5032e 100644
--- a/test/mjsunit/object-define-properties.js
+++ b/test/mjsunit/object-define-properties.js
@@ -54,3 +54,19 @@
 
 assertEquals(x.foo, 10);
 assertEquals(x.bar, 42);
+
+
+// Make sure that all property descriptors are calculated before any
+// modifications are done.
+
+var object = {};
+
+assertThrows(function() {
+    Object.defineProperties(object, {
+      foo: { value: 1 },
+      bar: { value: 2, get: function() { return 3; } }
+    });
+  }, TypeError);
+
+assertEquals(undefined, object.foo);
+assertEquals(undefined, object.bar);
diff --git a/test/mjsunit/cyclic-error-to-string.js b/test/mjsunit/optimized-typeof.js
similarity index 79%
copy from test/mjsunit/cyclic-error-to-string.js
copy to test/mjsunit/optimized-typeof.js
index 2502b53..b0c0725 100644
--- a/test/mjsunit/cyclic-error-to-string.js
+++ b/test/mjsunit/optimized-typeof.js
@@ -25,22 +25,23 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Test printing of cyclic errors which return the empty string for
-// compatibility with Safari and Firefox.
+// Flags: --allow-natives-syntax
 
-var e = new Error();
-assertEquals('Error', e + '');
+function typeofDirectly() {
+  return typeof({}) === "undefined";
+}
 
-e = new Error();
-e.name = e;
-e.message = e;
-e.stack = e;
-e.arguments = e;
-assertEquals(': ', e + '');
+typeofDirectly();
+typeofDirectly();
+%OptimizeFunctionOnNextCall(typeofDirectly);
+typeofDirectly();
 
-e = new Error();
-e.name = [ e ];
-e.message = [ e ];
-e.stack = [ e ];
-e.arguments = [ e ];
-assertEquals(': ', e + '');
+function typeofViaVariable() {
+  var foo = typeof({})
+  return foo === "undefined";
+}
+
+typeofViaVariable();
+typeofViaVariable();
+%OptimizeFunctionOnNextCall(typeofViaVariable);
+typeofViaVariable();
diff --git a/test/mjsunit/regexp-static.js b/test/mjsunit/regexp-static.js
index 0f84968..8f283f6 100644
--- a/test/mjsunit/regexp-static.js
+++ b/test/mjsunit/regexp-static.js
@@ -25,18 +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.
 
-// Test that we throw exceptions when calling test and exec with no
-// input.  This is not part of the spec, but we do it for
-// compatibility with JSC.
-assertThrows("/a/.test()");
-assertThrows("/a/.exec()");
-
-// Test that we do not throw exceptions once the static RegExp.input
-// field has been set.
-RegExp.input = "a";
-assertDoesNotThrow("/a/.test()");
-assertDoesNotThrow("/a/.exec()");
-
 // Test the (deprecated as of JS 1.5) properties of the RegExp function.
 var re = /((\d+)\.(\d+))/;
 var s = 'abc123.456def';
@@ -166,3 +154,8 @@
 var foo = "lsdfj sldkfj sdklfj læsdfjl sdkfjlsdk fjsdl fjsdljskdj flsj flsdkj flskd regexp: /foobar/\nldkfj sdlkfj sdkl";
 assertTrue(/^([a-z]+): (.*)/.test(foo.substring(foo.indexOf("regexp:"))), "regexp: setup");
 assertEquals("regexp", RegExp.$1, "RegExp.$1");
+
+
+// Check that calling with no argument is the same as calling with undefined.
+assertTrue(/^undefined$/.test());
+assertEquals(["undefined"], /^undefined$/.exec());
diff --git a/test/mjsunit/cyclic-error-to-string.js b/test/mjsunit/regress/regress-100702.js
similarity index 79%
copy from test/mjsunit/cyclic-error-to-string.js
copy to test/mjsunit/regress/regress-100702.js
index 2502b53..46494ab 100644
--- a/test/mjsunit/cyclic-error-to-string.js
+++ b/test/mjsunit/regress/regress-100702.js
@@ -25,22 +25,20 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Test printing of cyclic errors which return the empty string for
-// compatibility with Safari and Firefox.
+// Regression test for correct handling of non-object receiver values
+// passed to built-in array functions.
 
-var e = new Error();
-assertEquals('Error', e + '');
+String.prototype.isThatMe = function () {
+  assertFalse(this === str);
+};
 
-e = new Error();
-e.name = e;
-e.message = e;
-e.stack = e;
-e.arguments = e;
-assertEquals(': ', e + '');
+var str = "abc";
+str.isThatMe();
+str.isThatMe.call(str);
 
-e = new Error();
-e.name = [ e ];
-e.message = [ e ];
-e.stack = [ e ];
-e.arguments = [ e ];
-assertEquals(': ', e + '');
+var arr = [1];
+arr.forEach("".isThatMe, str);
+arr.filter("".isThatMe, str);
+arr.some("".isThatMe, str);
+arr.every("".isThatMe, str);
+arr.map("".isThatMe, str);
diff --git a/test/mjsunit/cyclic-error-to-string.js b/test/mjsunit/regress/regress-109195.js
similarity index 66%
copy from test/mjsunit/cyclic-error-to-string.js
copy to test/mjsunit/regress/regress-109195.js
index 2502b53..97538aa 100644
--- a/test/mjsunit/cyclic-error-to-string.js
+++ b/test/mjsunit/regress/regress-109195.js
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// 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:
@@ -25,22 +25,41 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Test printing of cyclic errors which return the empty string for
-// compatibility with Safari and Firefox.
+// Flags: --expose-debug-as debug
+var Debug = debug.Debug;
 
-var e = new Error();
-assertEquals('Error', e + '');
+function listener(event, exec_state, event_data, data) {
+  for (var i = 0, n = exec_state.frameCount(); i < n; i++) {
+    exec_state.frame().scopeCount(i);
+  }
+  exec_state.prepareStep(Debug.StepAction.Continue, 1);
+}
 
-e = new Error();
-e.name = e;
-e.message = e;
-e.stack = e;
-e.arguments = e;
-assertEquals(': ', e + '');
+Debug.setListener(listener);
 
-e = new Error();
-e.name = [ e ];
-e.message = [ e ];
-e.stack = [ e ];
-e.arguments = [ e ];
-assertEquals(': ', e + '');
+var F = function () {
+  1, function () {
+    var d = 0;
+    (function () { d; });
+    debugger;
+  }();
+};
+
+var src = "(" + F.toString() + ")()";
+eval(src);
+
+Function.prototype.__defineGetter__("f", function () {
+  debugger;
+  return 0;
+});
+
+var G = function () {
+  1, function () {
+    var d = 0;
+    (function () { d; });
+    debugger;
+  }['f'];
+};
+
+var src = "(" + G.toString() + ")()";
+eval(src);
diff --git a/test/mjsunit/regress/regress-1110.js b/test/mjsunit/regress/regress-1110.js
index 43b8d77..124f520 100644
--- a/test/mjsunit/regress/regress-1110.js
+++ b/test/mjsunit/regress/regress-1110.js
@@ -28,10 +28,9 @@
 // Test that the illegal continue is thrown at parse time.
 
 try {
-  function Crash() { continue;if (Crash) {
-    } }
+  eval("function Crash() { assertUnreachable(); continue;if (Crash) {  } }");
   Crash();
-  assertTrue(false);
+  assertUnreachable();
 } catch (e) {
   assertTrue(e instanceof SyntaxError);
   assertTrue(/continue/.test(e.message));
diff --git a/test/mjsunit/regress/regress-1170.js b/test/mjsunit/regress/regress-1170.js
index 95684c5..66ed9f2 100644
--- a/test/mjsunit/regress/regress-1170.js
+++ b/test/mjsunit/regress/regress-1170.js
@@ -49,7 +49,7 @@
   exception = true;
   assertTrue(/TypeError/.test(e));
 }
-assertTrue(exception);
+assertFalse(exception);
 
 exception = false;
 try {
diff --git a/test/mjsunit/regress/regress-1213575.js b/test/mjsunit/regress/regress-1213575.js
index 9d82064..f3a11db 100644
--- a/test/mjsunit/regress/regress-1213575.js
+++ b/test/mjsunit/regress/regress-1213575.js
@@ -25,17 +25,16 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Make sure that a const definition always
-// conflicts with a defined setter. This avoid
-// trying to pass 'the hole' to the setter.
+// Make sure that a const definition does not try
+// to pass 'the hole' to a defined setter.
 
-this.__defineSetter__('x', function(value) { assertTrue(false); });
+this.__defineSetter__('x', function(value) { assertTrue(value === 1); });
 
 var caught = false;
 try {
-  eval('const x');
+  eval('const x = 1');
 } catch(e) {
   assertTrue(e instanceof TypeError);
   caught = true;
 }
-assertTrue(caught);
+assertFalse(caught);
diff --git a/test/mjsunit/cyclic-error-to-string.js b/test/mjsunit/regress/regress-1217.js
similarity index 68%
copy from test/mjsunit/cyclic-error-to-string.js
copy to test/mjsunit/regress/regress-1217.js
index 2502b53..6530549 100644
--- a/test/mjsunit/cyclic-error-to-string.js
+++ b/test/mjsunit/regress/regress-1217.js
@@ -25,22 +25,26 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Test printing of cyclic errors which return the empty string for
-// compatibility with Safari and Firefox.
+// Check that RegExp.prototype is itself a RegExp object.
 
-var e = new Error();
-assertEquals('Error', e + '');
+var proto = RegExp.prototype;
+assertEquals("[object RegExp]", Object.prototype.toString.call(proto));
 
-e = new Error();
-e.name = e;
-e.message = e;
-e.stack = e;
-e.arguments = e;
-assertEquals(': ', e + '');
+assertEquals("", proto.source);
+assertEquals(false, proto.global);
+assertEquals(false, proto.multiline);
+assertEquals(false, proto.ignoreCase);
+assertEquals(0, proto.lastIndex);
 
-e = new Error();
-e.name = [ e ];
-e.message = [ e ];
-e.stack = [ e ];
-e.arguments = [ e ];
-assertEquals(': ', e + '');
+assertEquals("/(?:)/", proto.toString());
+
+var execResult = proto.exec("argle");
+assertEquals(1, execResult.length);
+assertEquals("", execResult[0]);
+assertEquals("argle", execResult.input);
+assertEquals(0, execResult.index);
+
+assertTrue(proto.test("argle"));
+
+// We disallow re-compiling the RegExp.prototype object.
+assertThrows(function(){ proto.compile("something"); }, TypeError);
diff --git a/test/mjsunit/regress/regress-1229.js b/test/mjsunit/regress/regress-1229.js
index e16d278..c0dcba9 100644
--- a/test/mjsunit/regress/regress-1229.js
+++ b/test/mjsunit/regress/regress-1229.js
@@ -35,10 +35,10 @@
   assertEquals(3, z);
 }
 
-var bound_arg = [1];
+var foob = foo.bind({}, 1);
 
 function f(y, z) {
-  return %NewObjectFromBound(foo, bound_arg);
+  return %NewObjectFromBound(foob);
 }
 
 // Check that %NewObjectFromBound looks at correct frame for inlined function.
diff --git a/test/mjsunit/cyclic-error-to-string.js b/test/mjsunit/regress/regress-1415.js
similarity index 73%
copy from test/mjsunit/cyclic-error-to-string.js
copy to test/mjsunit/regress/regress-1415.js
index 2502b53..f993e9b 100644
--- a/test/mjsunit/cyclic-error-to-string.js
+++ b/test/mjsunit/regress/regress-1415.js
@@ -25,22 +25,18 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Test printing of cyclic errors which return the empty string for
-// compatibility with Safari and Firefox.
+// Surrogate pair range.
+// U+D800
+assertThrows(function(){ decodeURIComponent("%ED%A0%80"); }, URIError);
+// U+DBFF
+assertThrows(function(){ decodeURIComponent("%ED%AF%BF"); }, URIError);
+// U+DC00
+assertThrows(function(){ decodeURIComponent("%ED%B0%80"); }, URIError);
+// U+DFFF
+assertThrows(function(){ decodeURIComponent("%ED%BF%BF"); }, URIError);
 
-var e = new Error();
-assertEquals('Error', e + '');
-
-e = new Error();
-e.name = e;
-e.message = e;
-e.stack = e;
-e.arguments = e;
-assertEquals(': ', e + '');
-
-e = new Error();
-e.name = [ e ];
-e.message = [ e ];
-e.stack = [ e ];
-e.arguments = [ e ];
-assertEquals(': ', e + '');
+// Overlong encodings
+// U+007F in two bytes.
+assertThrows(function(){ decodeURIComponent("%C1%BF"); }, URIError);
+// U+07FF in three bytes.
+assertThrows(function(){ decodeURIComponent("%E0%9F%BF"); }, URIError);
diff --git a/test/mjsunit/regress/regress-1639-2.js b/test/mjsunit/regress/regress-1639-2.js
new file mode 100644
index 0000000..c439dd8
--- /dev/null
+++ b/test/mjsunit/regress/regress-1639-2.js
@@ -0,0 +1,93 @@
+// 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: --expose-debug-as debug
+// Get the Debug object exposed from the debug context global object.
+Debug = debug.Debug
+
+function sendCommand(state, cmd) {
+  // Get the debug command processor in paused state.
+  var dcp = state.debugCommandProcessor(false);
+  var request = JSON.stringify(cmd);
+  var response = dcp.processDebugJSONRequest(request);
+}
+
+var state = 0;
+
+function listener(event, exec_state, event_data, data) {
+  try {
+    if (event == Debug.DebugEvent.Break) {
+      var line = event_data.sourceLineText();
+      print('break: ' + line);
+      print('event data: ' + event_data.toJSONProtocol());
+      print();
+      assertEquals('// BREAK', line.substr(-8),
+                   "should not break outside evaluate");
+
+      switch (state) {
+      case 0:
+        state = 1;
+        // While in the debugger and stepping through a set of instructions
+        // executed in the evaluate command, the stepping must stop at the end
+        // of the said set of instructions and not step further into native
+        // debugger code.
+        sendCommand(exec_state, {
+          seq : 0,
+          type : "request",
+          command : "evaluate",
+          arguments : {
+            'expression' : 'print("A"); debugger; print("B"); // BREAK',
+            'global' : true
+          }
+        });
+        break;
+      case 1:
+        sendCommand(exec_state, {
+          seq : 0,
+          type : "request",
+          command : "continue",
+          arguments : {
+            stepaction : "next"
+          }
+        });
+        break;
+      }
+    }
+  } catch (e) {
+    print(e);
+  }
+}
+
+// Add the debug event listener.
+Debug.setListener(listener);
+
+function a() {
+} // BREAK
+
+// Set a break point and call to invoke the debug event listener.
+Debug.setBreakPoint(a, 0, 0);
+a();
diff --git a/test/mjsunit/regress/regress-1692.js b/test/mjsunit/regress/regress-1692.js
new file mode 100644
index 0000000..06bd66c
--- /dev/null
+++ b/test/mjsunit/regress/regress-1692.js
@@ -0,0 +1,89 @@
+// 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.
+
+// Test that Object.prototype.propertyIsEnumerable handles array indices
+// correctly.
+
+var p = Object.create({}, {
+  a : { value : 42, enumerable : true },
+  b : { value : 42, enumerable : false },
+  1 : { value : 42, enumerable : true },
+  2 : { value : 42, enumerable : false },
+  f : { get: function(){}, enumerable: true },
+  g : { get: function(){}, enumerable: false },
+  11 : { get: function(){}, enumerable: true },
+  12 : { get: function(){}, enumerable: false }
+});
+var o = Object.create(p, {
+  c : { value : 42, enumerable : true },
+  d : { value : 42, enumerable : false },
+  3 : { value : 42, enumerable : true },
+  4 : { value : 42, enumerable : false },
+  h : { get: function(){}, enumerable: true },
+  k : { get: function(){}, enumerable: false },
+  13 : { get: function(){}, enumerable: true },
+  14 : { get: function(){}, enumerable: false }
+});
+
+// Inherited properties are ignored.
+assertFalse(o.propertyIsEnumerable("a"));
+assertFalse(o.propertyIsEnumerable("b"));
+assertFalse(o.propertyIsEnumerable("1"));
+assertFalse(o.propertyIsEnumerable("2"));
+
+// Own properties.
+assertTrue(o.propertyIsEnumerable("c"));
+assertFalse(o.propertyIsEnumerable("d"));
+assertTrue(o.propertyIsEnumerable("3"));
+assertFalse(o.propertyIsEnumerable("4"));
+
+// Inherited accessors.
+assertFalse(o.propertyIsEnumerable("f"));
+assertFalse(o.propertyIsEnumerable("g"));
+assertFalse(o.propertyIsEnumerable("11"));
+assertFalse(o.propertyIsEnumerable("12"));
+
+// Own accessors.
+assertTrue(o.propertyIsEnumerable("h"));
+assertFalse(o.propertyIsEnumerable("k"));
+assertTrue(o.propertyIsEnumerable("13"));
+assertFalse(o.propertyIsEnumerable("14"));
+
+// Nonexisting properties.
+assertFalse(o.propertyIsEnumerable("xxx"));
+assertFalse(o.propertyIsEnumerable("999"));
+
+// String object properties.
+var o = Object("string");
+// Non-string property on String object.
+o[10] = 42;
+assertTrue(o.propertyIsEnumerable(10));
+assertFalse(o.propertyIsEnumerable(0));
+
+// Fast elements.
+var o = [1,2,3,4,5];
+assertTrue(o.propertyIsEnumerable(3));
diff --git a/test/mjsunit/regress/regress-1708.js b/test/mjsunit/regress/regress-1708.js
new file mode 100644
index 0000000..ab50e07
--- /dev/null
+++ b/test/mjsunit/regress/regress-1708.js
@@ -0,0 +1,63 @@
+// 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.
+
+// Regression test of a very rare corner case where left-trimming an
+// array caused invalid marking bit patterns on lazily swept pages.
+
+// Flags: --expose-gc --noincremental-marking --max-new-space-size 1000
+
+(function() {
+  var head = new Array(1);
+  var tail = head;
+
+  // Fill heap to increase old-space size and trigger lazy sweeping on
+  // some of the old-space pages.
+  for (var i = 0; i < 200; i++) {
+    tail[1] = new Array(1000);
+    tail = tail[1];
+  }
+  array = new Array(100);
+  gc(); gc();
+
+  // At this point "array" should have been promoted to old-space and be
+  // located in a lazy swept page with intact marking bits. Now shift
+  // the array to trigger left-trimming operations.
+  assertEquals(100, array.length);
+  for (var i = 0; i < 50; i++) {
+    array.shift();
+  }
+  assertEquals(50, array.length);
+
+  // At this point "array" should have been trimmed from the left with
+  // marking bits being correctly transfered to the new object start.
+  // Scavenging operations cause lazy sweeping to advance and verify
+  // that marking bit patterns are still sane.
+  for (var i = 0; i < 200; i++) {
+    tail[1] = new Array(1000);
+    tail = tail[1];
+  }
+})();
diff --git a/test/mjsunit/cyclic-error-to-string.js b/test/mjsunit/regress/regress-1711.js
similarity index 80%
copy from test/mjsunit/cyclic-error-to-string.js
copy to test/mjsunit/regress/regress-1711.js
index 2502b53..15591b1 100644
--- a/test/mjsunit/cyclic-error-to-string.js
+++ b/test/mjsunit/regress/regress-1711.js
@@ -25,22 +25,14 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Test printing of cyclic errors which return the empty string for
-// compatibility with Safari and Firefox.
+// string.split needs to evaluate the separator's toString even if limit
+// is 0 because toString may have side effects.
 
-var e = new Error();
-assertEquals('Error', e + '');
-
-e = new Error();
-e.name = e;
-e.message = e;
-e.stack = e;
-e.arguments = e;
-assertEquals(': ', e + '');
-
-e = new Error();
-e.name = [ e ];
-e.message = [ e ];
-e.stack = [ e ];
-e.arguments = [ e ];
-assertEquals(': ', e + '');
+var side_effect = false;
+var separator = new Object();
+separator.toString = function() {
+  side_effect = true;
+  return undefined;
+}
+'subject'.split(separator, 0);
+assertTrue(side_effect);
diff --git a/test/mjsunit/regress/regress-1713.js b/test/mjsunit/regress/regress-1713.js
new file mode 100644
index 0000000..0af1144
--- /dev/null
+++ b/test/mjsunit/regress/regress-1713.js
@@ -0,0 +1,127 @@
+// 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: --allow-natives-syntax --always-compact --expose-gc
+
+var O = { get f() { return 0; } };
+
+var CODE = [];
+
+var R = [];
+
+function Allocate4Kb(N) {
+  var arr = [];
+  do {arr.push(new Array(1024));} while (--N > 0);
+  return arr;
+}
+
+function AllocateXMb(X) {
+  return Allocate4Kb((1024 * X) / 4);
+}
+
+function Node(v, next) { this.v = v; this.next = next; }
+
+Node.prototype.execute = function (O) {
+  var n = this;
+  while (n.next !== null) n = n.next;
+  n.v(O);
+};
+
+function LongList(N, x) {
+  if (N == 0) return new Node(x, null);
+  return new Node(new Array(1024), LongList(N - 1, x));
+}
+
+var L = LongList(1024, function (O) {
+  for (var i = 0; i < 5; i++) O.f;
+});
+
+
+
+function Incremental(O, x) {
+  if (!x) {
+    return;
+  }
+  function CreateCode(i) {
+    var f = new Function("return O.f_" + i);
+    CODE.push(f);
+    f(); // compile
+    f(); // compile
+    f(); // compile
+  }
+
+  for (var i = 0; i < 1e4; i++) CreateCode(i);
+  gc();
+  gc();
+  gc();
+
+  print(">>> 1 <<<");
+
+  L.execute(O);
+
+  try {} catch (e) {}
+
+  L = null;
+  print(">>> 2 <<<");
+  AllocateXMb(8);
+ //rint("1");
+ //llocateXMb(8);
+ //rint("1");
+ //llocateXMb(8);
+
+}
+
+function foo(O, x) {
+  Incremental(O, x);
+
+  print('f');
+
+  for (var i = 0; i < 5; i++) O.f;
+
+
+  print('g');
+
+  bar(x);
+}
+
+function bar(x) {
+  if (!x) return;
+  %DeoptimizeFunction(foo);
+  AllocateXMb(8);
+  AllocateXMb(8);
+}
+
+var O1 = {};
+var O2 = {};
+var O3 = {};
+var O4 = {f:0};
+
+foo(O1, false);
+foo(O2, false);
+foo(O3, false);
+%OptimizeFunctionOnNextCall(foo);
+foo(O4, true);
diff --git a/test/mjsunit/cyclic-error-to-string.js b/test/mjsunit/regress/regress-1748.js
similarity index 80%
copy from test/mjsunit/cyclic-error-to-string.js
copy to test/mjsunit/regress/regress-1748.js
index 2502b53..e287e55 100644
--- a/test/mjsunit/cyclic-error-to-string.js
+++ b/test/mjsunit/regress/regress-1748.js
@@ -25,22 +25,11 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Test printing of cyclic errors which return the empty string for
-// compatibility with Safari and Firefox.
+// Test that /^/ only matches at beginning of string.
+// Bug in x64 caused it to match when executing the RegExp on a part
+// of a string that starts at a multiplum of 256.
 
-var e = new Error();
-assertEquals('Error', e + '');
-
-e = new Error();
-e.name = e;
-e.message = e;
-e.stack = e;
-e.arguments = e;
-assertEquals(': ', e + '');
-
-e = new Error();
-e.name = [ e ];
-e.message = [ e ];
-e.stack = [ e ];
-e.arguments = [ e ];
-assertEquals(': ', e + '');
+var str = Array(10000).join("X");
+str.replace(/^|X/g, function(m, i, s) {
+  if (i > 0) assertEquals("X", m, "at position 0x" + i.toString(16));
+});
\ No newline at end of file
diff --git a/test/mjsunit/regress/regress-221.js b/test/mjsunit/regress/regress-1757.js
similarity index 85%
rename from test/mjsunit/regress/regress-221.js
rename to test/mjsunit/regress/regress-1757.js
index d3f2e35..f7a5516 100644
--- a/test/mjsunit/regress/regress-221.js
+++ b/test/mjsunit/regress/regress-1757.js
@@ -1,4 +1,4 @@
-// Copyright 2009 the V8 project authors. All rights reserved.
+// 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:
@@ -25,10 +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.
 
-// Test that direct eval calls handle the case where eval has been
-// deleted correctly.
+// Flags: --string-slices --expose-externalize-string
 
-// See http://code.google.com/p/v8/issues/detail?id=221
-
-assertThrows('eval(delete eval)');
-
+var a = "abcdefghijklmnopqrstuvqxy"+"z";
+externalizeString(a, true);
+assertEquals('b', a.substring(1).charAt(0));
\ No newline at end of file
diff --git a/test/mjsunit/regress/regress-221.js b/test/mjsunit/regress/regress-1945.js
similarity index 85%
copy from test/mjsunit/regress/regress-221.js
copy to test/mjsunit/regress/regress-1945.js
index d3f2e35..bffc775 100644
--- a/test/mjsunit/regress/regress-221.js
+++ b/test/mjsunit/regress/regress-1945.js
@@ -1,4 +1,4 @@
-// Copyright 2009 the V8 project authors. All rights reserved.
+// 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:
@@ -25,10 +25,10 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Test that direct eval calls handle the case where eval has been
-// deleted correctly.
+// Flags: --allow-natives-syntax
 
-// See http://code.google.com/p/v8/issues/detail?id=221
-
-assertThrows('eval(delete eval)');
-
+var _d = new Date();
+_d.setHours(0,0,0,0);
+_d.setHours(0,0,0,0);
+%OptimizeFunctionOnNextCall(_d.setHours);
+_d.setHours(0,0,0,0);
diff --git a/test/mjsunit/regress/regress-877615.js b/test/mjsunit/regress/regress-877615.js
index d35aba6..bec5a4d 100644
--- a/test/mjsunit/regress/regress-877615.js
+++ b/test/mjsunit/regress/regress-877615.js
@@ -25,13 +25,13 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-Number.prototype.toLocaleString = function() { return 'invalid'};
-assertEquals([1].toLocaleString(), 'invalid');  // invalid
+Number.prototype.toLocaleString = function() { return 'invalid'; };
+assertEquals('invalid', [1].toLocaleString());  // invalid
 
 Number.prototype.toLocaleString = 'invalid';
-assertEquals([1].toLocaleString(), '1');  // 1
+assertThrows(function() { [1].toLocaleString(); });  // Not callable.
 
+delete Number.prototype.toLocaleString;
 Number.prototype.toString = function() { return 'invalid' };
-assertEquals([1].toLocaleString(), '1');  // 1
-assertEquals([1].toString(), '1');        // 1
-
+assertEquals([1].toLocaleString(), 'invalid');  // Uses ToObject on elements.
+assertEquals([1].toString(), '1');        // Uses ToString directly on elements.
diff --git a/test/mjsunit/regress/regress-91517.js b/test/mjsunit/regress/regress-91517.js
deleted file mode 100644
index 68a768c..0000000
--- a/test/mjsunit/regress/regress-91517.js
+++ /dev/null
@@ -1,112 +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.
-
-// Getting property names of an object with a prototype chain that
-// triggers dictionary elements in GetLocalPropertyNames() shouldn't
-// crash the runtime
-
-// Flags: --allow-natives-syntax
-
-function Object1() {
-  this.foo = 1;
-}
-
-function Object2() {
-  this.fuz = 2;
-  this.objects = new Object();
-  this.fuz1 = 2;
-  this.fuz2 = 2;
-  this.fuz3 = 2;
-  this.fuz4 = 2;
-  this.fuz5 = 2;
-  this.fuz6 = 2;
-  this.fuz7 = 2;
-  this.fuz8 = 2;
-  this.fuz9 = 2;
-  this.fuz10 = 2;
-  this.fuz11 = 2;
-  this.fuz12 = 2;
-  this.fuz13 = 2;
-  this.fuz14 = 2;
-  this.fuz15 = 2;
-  this.fuz16 = 2;
-  this.fuz17 = 2;
-  // Force dictionary-based properties
-  for (x=1;x<1000;x++) {
-    this["sdf" + x] = 2;
-  }
-}
-
-function Object3() {
-  this.boo = 3;
-}
-
-function Object4() {
-  this.baz = 4;
-}
-
-obj1 = new Object1();
-obj2 = new Object2();
-obj3 = new Object3();
-obj4 = new Object4();
-
-%SetHiddenPrototype(obj4, obj3);
-%SetHiddenPrototype(obj3, obj2);
-%SetHiddenPrototype(obj2, obj1);
-
-function contains(a, obj) {
-  for(var i = 0; i < a.length; i++) {
-    if(a[i] === obj){
-      return true;
-    }
-  }
-  return false;
-}
-names = %GetLocalPropertyNames(obj4);
-assertEquals(1021, names.length);
-assertTrue(contains(names, "baz"));
-assertTrue(contains(names, "boo"));
-assertTrue(contains(names, "foo"));
-assertTrue(contains(names, "fuz"));
-assertTrue(contains(names, "fuz1"));
-assertTrue(contains(names, "fuz2"));
-assertTrue(contains(names, "fuz3"));
-assertTrue(contains(names, "fuz4"));
-assertTrue(contains(names, "fuz5"));
-assertTrue(contains(names, "fuz6"));
-assertTrue(contains(names, "fuz7"));
-assertTrue(contains(names, "fuz8"));
-assertTrue(contains(names, "fuz9"));
-assertTrue(contains(names, "fuz10"));
-assertTrue(contains(names, "fuz11"));
-assertTrue(contains(names, "fuz12"));
-assertTrue(contains(names, "fuz13"));
-assertTrue(contains(names, "fuz14"));
-assertTrue(contains(names, "fuz15"));
-assertTrue(contains(names, "fuz16"));
-assertTrue(contains(names, "fuz17"));
-assertFalse(names[1020] == undefined);
diff --git a/test/mjsunit/regress/regress-94873.js b/test/mjsunit/regress/regress-94873.js
new file mode 100644
index 0000000..41ca992
--- /dev/null
+++ b/test/mjsunit/regress/regress-94873.js
@@ -0,0 +1,78 @@
+// 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: --expose-debug-as debug
+// Get the Debug object exposed from the debug context global object.
+Debug = debug.Debug;
+
+function sendCommand(state, cmd) {
+  // Get the debug command processor in paused state.
+  var dcp = state.debugCommandProcessor(false);
+  var request = JSON.stringify(cmd);
+  var response = dcp.processDebugJSONRequest(request);
+  return JSON.parse(response);
+}
+
+function listener(event, exec_state, event_data, data) {
+  try {
+    if (event == Debug.DebugEvent.Break) {
+      var line = event_data.sourceLineText();
+      print('break: ' + line);
+
+      var frame = sendCommand(exec_state, {
+        seq: 0,
+        type: "request",
+        command: "frame"
+      });
+
+      sendCommand(exec_state, {
+        seq: 0,
+        type: "request",
+        command: "evaluate",
+        arguments: {
+          expression: "obj.x.toString()",
+          additional_context: [{
+            name: "obj",
+            handle: frame.body.receiver.ref
+          }]
+        }
+      });
+    }
+  } catch (e) {
+    print(e);
+  }
+}
+
+Debug.setListener(listener);
+
+function a(x, y) {
+  this.x = x;
+  this.y = y;
+}
+
+Debug.setBreakPoint(a, 0, 0);
+new a(1, 2);
\ No newline at end of file
diff --git a/test/mjsunit/cyclic-error-to-string.js b/test/mjsunit/regress/regress-98773.js
similarity index 80%
copy from test/mjsunit/cyclic-error-to-string.js
copy to test/mjsunit/regress/regress-98773.js
index 2502b53..eb24eb5 100644
--- a/test/mjsunit/cyclic-error-to-string.js
+++ b/test/mjsunit/regress/regress-98773.js
@@ -25,22 +25,15 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Test printing of cyclic errors which return the empty string for
-// compatibility with Safari and Firefox.
+// Calling Array.sort on an external array is not supposed to crash.
 
-var e = new Error();
-assertEquals('Error', e + '');
+var array = new Int16Array(23);
+array[7] = 7; array[9] = 9;
+assertEquals(23, array.length);
+assertEquals(7, array[7]);
+assertEquals(9, array[9]);
 
-e = new Error();
-e.name = e;
-e.message = e;
-e.stack = e;
-e.arguments = e;
-assertEquals(': ', e + '');
-
-e = new Error();
-e.name = [ e ];
-e.message = [ e ];
-e.stack = [ e ];
-e.arguments = [ e ];
-assertEquals(': ', e + '');
+Array.prototype.sort.call(array);
+assertEquals(23, array.length);
+assertEquals(7, array[21]);
+assertEquals(9, array[22]);
diff --git a/test/mjsunit/regress/regress-221.js b/test/mjsunit/regress/regress-99167.js
similarity index 85%
copy from test/mjsunit/regress/regress-221.js
copy to test/mjsunit/regress/regress-99167.js
index d3f2e35..5053ae5 100644
--- a/test/mjsunit/regress/regress-221.js
+++ b/test/mjsunit/regress/regress-99167.js
@@ -1,4 +1,4 @@
-// Copyright 2009 the V8 project authors. All rights reserved.
+// 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:
@@ -25,10 +25,9 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Test that direct eval calls handle the case where eval has been
-// deleted correctly.
+// Flags: --expose-gc --max-new-space-size=1024
 
-// See http://code.google.com/p/v8/issues/detail?id=221
-
-assertThrows('eval(delete eval)');
-
+eval("function Node() { this.a = 1; this.a = 3; }");
+new Node;
+for (var i = 0; i < 4; ++i) gc();
+for (var i = 0; i < 100000; ++i) new Node;
diff --git a/test/mjsunit/cyclic-error-to-string.js b/test/mjsunit/regress/regress-crbug-107996.js
similarity index 64%
copy from test/mjsunit/cyclic-error-to-string.js
copy to test/mjsunit/regress/regress-crbug-107996.js
index 2502b53..dfe07e5 100644
--- a/test/mjsunit/cyclic-error-to-string.js
+++ b/test/mjsunit/regress/regress-crbug-107996.js
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// 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:
@@ -25,22 +25,40 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Test printing of cyclic errors which return the empty string for
-// compatibility with Safari and Firefox.
+// Flags: --expose-debug-as debug
 
-var e = new Error();
-assertEquals('Error', e + '');
+Debug = debug.Debug;
 
-e = new Error();
-e.name = e;
-e.message = e;
-e.stack = e;
-e.arguments = e;
-assertEquals(': ', e + '');
+Debug.setListener(listener);
 
-e = new Error();
-e.name = [ e ];
-e.message = [ e ];
-e.stack = [ e ];
-e.arguments = [ e ];
-assertEquals(': ', e + '');
+var fourteen;
+var four_in_debugger = [];
+
+function listener(event, exec_state, event_data, data) {
+  if (event == Debug.DebugEvent.Break) {
+    for (var i = 0; i < exec_state.frameCount(); i++) {
+      var frame = exec_state.frame(i);
+      four_in_debugger[i] = frame.evaluate("four", false).value();
+    }
+  }
+}
+
+function f1() {
+  var three = 3;
+  var four = 4;
+  (function f2() {
+     var seven = 7;
+     (function f3() {
+        debugger;
+        fourteen = three + four + seven;
+     })();
+  })();
+}
+
+f1();
+assertEquals(14, fourteen);
+assertEquals(4, four_in_debugger[0]);
+assertEquals(4, four_in_debugger[1]);
+assertEquals(4, four_in_debugger[2]);
+
+Debug.setListener(null);
diff --git a/test/mjsunit/regress/regress-deopt-gc.js b/test/mjsunit/regress/regress-deopt-gc.js
index 7b7c29a..a74e2c5 100644
--- a/test/mjsunit/regress/regress-deopt-gc.js
+++ b/test/mjsunit/regress/regress-deopt-gc.js
@@ -42,7 +42,7 @@
   // Make sure we don't inline this function
   try { var a = 42; } catch(o) {};
   %DeoptimizeFunction(opt_me);
-  gc(true);
+  gc();
 }
 
 
diff --git a/test/mjsunit/regress/regress-221.js b/test/mjsunit/regress/short-circuit.js
similarity index 85%
copy from test/mjsunit/regress/regress-221.js
copy to test/mjsunit/regress/short-circuit.js
index d3f2e35..25363d6 100644
--- a/test/mjsunit/regress/regress-221.js
+++ b/test/mjsunit/regress/short-circuit.js
@@ -1,4 +1,4 @@
-// Copyright 2009 the V8 project authors. All rights reserved.
+// 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:
@@ -25,10 +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.
 
-// Test that direct eval calls handle the case where eval has been
-// deleted correctly.
+var arr = [];
 
-// See http://code.google.com/p/v8/issues/detail?id=221
-
-assertThrows('eval(delete eval)');
-
+for (var i = 0; i < 28000; i++) {
+  arr.push(new RegExp("prefix" + i.toString() + i.toString() + i.toString()));
+}
diff --git a/test/mjsunit/stack-traces-2.js b/test/mjsunit/stack-traces-2.js
new file mode 100644
index 0000000..165c4df
--- /dev/null
+++ b/test/mjsunit/stack-traces-2.js
@@ -0,0 +1,87 @@
+// 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: --builtins-in-stack-traces
+
+
+// Poisonous object that throws a reference error if attempted converted to
+// a primitive values.
+var thrower = { valueOf: function() { FAIL; },
+                toString: function() { FAIL; } };
+
+// Tests that a native constructor function is included in the
+// stack trace.
+function testTraceNativeConstructor(nativeFunc) {
+  var nativeFuncName = nativeFunc.name;
+  try {
+    new nativeFunc(thrower);
+    assertUnreachable(nativeFuncName);
+  } catch (e) {
+    assertTrue(e.stack.indexOf(nativeFuncName) >= 0, nativeFuncName);
+  }
+}
+
+// Tests that a native conversion function is included in the
+// stack trace.
+function testTraceNativeConversion(nativeFunc) {
+  var nativeFuncName = nativeFunc.name;
+  try {
+    nativeFunc(thrower);
+    assertUnreachable(nativeFuncName);
+  } catch (e) {
+    assertTrue(e.stack.indexOf(nativeFuncName) >= 0, nativeFuncName);
+  }
+}
+
+
+function testNotOmittedBuiltin(throwing, included) {
+  try {
+    throwing();
+    assertUnreachable(included);
+  } catch (e) {
+    assertTrue(e.stack.indexOf(included) >= 0, included);
+  }
+}
+
+
+testTraceNativeConversion(String);  // Does ToString on argument.
+testTraceNativeConversion(Number);  // Does ToNumber on argument.
+testTraceNativeConversion(RegExp);  // Does ToString on argument.
+
+testTraceNativeConstructor(String);  // Does ToString on argument.
+testTraceNativeConstructor(Number);  // Does ToNumber on argument.
+testTraceNativeConstructor(RegExp);  // Does ToString on argument.
+testTraceNativeConstructor(Date);    // Does ToNumber on argument.
+
+// QuickSort has builtins object as receiver, and is non-native
+// builtin. Should not be omitted with the --builtins-in-stack-traces flag.
+testNotOmittedBuiltin(function(){ [thrower, 2].sort(function (a,b) {
+                                                     (b < a) - (a < b); });
+                      }, "QuickSort");
+
+// Not omitted even though ADD from runtime.js is a non-native builtin.
+testNotOmittedBuiltin(function(){ thrower + 2; }, "ADD");
\ No newline at end of file
diff --git a/test/mjsunit/stack-traces.js b/test/mjsunit/stack-traces.js
index 47a5cc5..536e71b 100644
--- a/test/mjsunit/stack-traces.js
+++ b/test/mjsunit/stack-traces.js
@@ -194,6 +194,46 @@
 }
 
 
+// Poisonous object that throws a reference error if attempted converted to
+// a primitive values.
+var thrower = { valueOf: function() { FAIL; },
+                toString: function() { FAIL; } };
+
+// Tests that a native constructor function is included in the
+// stack trace.
+function testTraceNativeConstructor(nativeFunc) {
+  var nativeFuncName = nativeFunc.name;
+  try {
+    new nativeFunc(thrower);
+    assertUnreachable(nativeFuncName);
+  } catch (e) {
+    assertTrue(e.stack.indexOf(nativeFuncName) >= 0, nativeFuncName);
+  }
+}
+
+// Tests that a native conversion function is included in the
+// stack trace.
+function testTraceNativeConversion(nativeFunc) {
+  var nativeFuncName = nativeFunc.name;
+  try {
+    nativeFunc(thrower);
+    assertUnreachable(nativeFuncName);
+  } catch (e) {
+    assertTrue(e.stack.indexOf(nativeFuncName) >= 0, nativeFuncName);
+  }
+}
+
+
+function testOmittedBuiltin(throwing, omitted) {
+  try {
+    throwing();
+    assertUnreachable(omitted);
+  } catch (e) {
+    assertTrue(e.stack.indexOf(omitted) < 0, omitted);
+  }
+}
+
+
 testTrace("testArrayNative", testArrayNative, ["Array.map (native)"]);
 testTrace("testNested", testNested, ["at one", "at two", "at three"]);
 testTrace("testMethodNameInference", testMethodNameInference, ["at Foo.bar"]);
@@ -217,3 +257,21 @@
 testCallerCensorship();
 testUnintendedCallerCensorship();
 testErrorsDuringFormatting();
+
+testTraceNativeConversion(String);  // Does ToString on argument.
+testTraceNativeConversion(Number);  // Does ToNumber on argument.
+testTraceNativeConversion(RegExp);  // Does ToString on argument.
+
+testTraceNativeConstructor(String);  // Does ToString on argument.
+testTraceNativeConstructor(Number);  // Does ToNumber on argument.
+testTraceNativeConstructor(RegExp);  // Does ToString on argument.
+testTraceNativeConstructor(Date);    // Does ToNumber on argument.
+
+// Omitted because QuickSort has builtins object as receiver, and is non-native
+// builtin.
+testOmittedBuiltin(function(){ [thrower, 2].sort(function (a,b) {
+                                                     (b < a) - (a < b); });
+                   }, "QuickSort");
+
+// Omitted because ADD from runtime.js is non-native builtin.
+testOmittedBuiltin(function(){ thrower + 2; }, "ADD");
\ No newline at end of file
diff --git a/test/mjsunit/strict-mode-implicit-receiver.js b/test/mjsunit/strict-mode-implicit-receiver.js
index 338f6d1..8284edd 100644
--- a/test/mjsunit/strict-mode-implicit-receiver.js
+++ b/test/mjsunit/strict-mode-implicit-receiver.js
@@ -168,12 +168,7 @@
 outer_eval_conversion3(strict_eval, 'undefined');
 outer_eval_conversion3(non_strict_eval, 'object');
 
-// TODO(ager): I'm not sure this is in accordance with the spec. At
-// the moment, any call to eval where eval is not bound in the global
-// context is treated as an indirect call to eval which means that the
-// global context is used and the global object is passed as the
-// receiver.
-outer_eval_conversion3(eval, 'object');
+outer_eval_conversion3(eval, 'undefined');
 
 function test_constant_function() {
   var o = { f: function() { "use strict"; return this; } };
diff --git a/test/mjsunit/strict-mode.js b/test/mjsunit/strict-mode.js
index 30234ba..9c9bdfd 100644
--- a/test/mjsunit/strict-mode.js
+++ b/test/mjsunit/strict-mode.js
@@ -1051,14 +1051,20 @@
   }
   assertThrows(function() { strict.caller; }, TypeError);
   assertThrows(function() { strict.arguments; }, TypeError);
+  assertThrows(function() { strict.caller = 42; }, TypeError);
+  assertThrows(function() { strict.arguments = 42; }, TypeError);
 
   var another = new Function("'use strict'");
   assertThrows(function() { another.caller; }, TypeError);
   assertThrows(function() { another.arguments; }, TypeError);
+  assertThrows(function() { another.caller = 42; }, TypeError);
+  assertThrows(function() { another.arguments = 42; }, TypeError);
 
   var third = (function() { "use strict"; return function() {}; })();
   assertThrows(function() { third.caller; }, TypeError);
   assertThrows(function() { third.arguments; }, TypeError);
+  assertThrows(function() { third.caller = 42; }, TypeError);
+  assertThrows(function() { third.arguments = 42; }, TypeError);
 
   CheckPillDescriptor(strict, "caller");
   CheckPillDescriptor(strict, "arguments");
diff --git a/test/mjsunit/string-external-cached.js b/test/mjsunit/string-external-cached.js
new file mode 100644
index 0000000..12312ac
--- /dev/null
+++ b/test/mjsunit/string-external-cached.js
@@ -0,0 +1,94 @@
+// Copyright 2010 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: --expose-externalize-string --expose-gc
+// Test data pointer caching of external strings.
+
+function test() {
+  // Test string.charAt.
+  var charat_str = new Array(5);
+  charat_str[0] = "0123456789ABCDEF0123456789ABCDEF\
+0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\
+0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\
+0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\
+0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF";
+  charat_str[1] = "0123456789ABCDEF";
+  for (var i = 0; i < 6; i++) charat_str[1] += charat_str[1];
+  try {  // String can only be externalized once
+    externalizeString(charat_str[0], false);
+    externalizeString(charat_str[1], true);
+  } catch (ex) { }
+  charat_str[2] = charat_str[0].slice(0, -1);
+  charat_str[3] = charat_str[1].slice(0, -1);
+  charat_str[4] = charat_str[0] + charat_str[0];
+
+  for (var i = 0; i < 5; i++) {
+    assertEquals('B', charat_str[i].charAt(6*16 + 11));
+    assertEquals('C', charat_str[i].charAt(6*16 + 12));
+    assertEquals('A', charat_str[i].charAt(3*16 + 10));
+    assertEquals('B', charat_str[i].charAt(3*16 + 11));
+  }
+
+  charat_short = "012";
+  try {  // String can only be externalized once
+    externalizeString(charat_short, true);
+  } catch (ex) { }
+  assertEquals("1", charat_short.charAt(1));
+
+  // Test regexp.
+  var re = /(A|B)/;
+  var rere = /(T.{1,2}B)/;
+  var ascii = "ABCDEFGHIJKLMNOPQRST";
+  var twobyte = "_ABCDEFGHIJKLMNOPQRST";
+  try {
+    externalizeString(ascii, false);
+    externalizeString(twobyte, true);
+  } catch (ex) { }
+  assertTrue(isAsciiString(ascii));
+  assertFalse(isAsciiString(twobyte));
+  var ascii_slice = ascii.slice(1,-1);
+  var twobyte_slice = twobyte.slice(2,-1);
+  var ascii_cons = ascii + ascii;
+  var twobyte_cons = twobyte + twobyte;
+  for (var i = 0; i < 2; i++) {
+    assertEquals(["A", "A"], re.exec(ascii));
+    assertEquals(["B", "B"], re.exec(ascii_slice));
+    assertEquals(["TAB", "TAB"], rere.exec(ascii_cons));
+    assertEquals(["A", "A"], re.exec(twobyte));
+    assertEquals(["B", "B"], re.exec(twobyte_slice));
+    assertEquals(["T_AB", "T_AB"], rere.exec(twobyte_cons));
+  }
+}
+
+// Run the test many times to ensure IC-s don't break things.
+for (var i = 0; i < 10; i++) {
+  test();
+}
+
+// Clean up string to make Valgrind happy.
+gc();
+gc();
diff --git a/test/mjsunit/string-externalize.js b/test/mjsunit/string-externalize.js
index da89786..d52a7e2 100644
--- a/test/mjsunit/string-externalize.js
+++ b/test/mjsunit/string-externalize.js
@@ -44,7 +44,7 @@
   assertFalse(isAsciiString(twoByteExternalWithAsciiData));
 
   var realTwoByteExternalString =
-      "\u1234\u1234" + (function() { return "\u1234"; })();
+      "\u1234\u1234\u1234\u1234" + (function() { return "\u1234"; })();
   externalizeString(realTwoByteExternalString);
   assertFalse(isAsciiString(realTwoByteExternalString));
 
diff --git a/test/mjsunit/string-slices-regexp.js b/test/mjsunit/string-slices-regexp.js
index a8cadae..98b8ef9 100644
--- a/test/mjsunit/string-slices-regexp.js
+++ b/test/mjsunit/string-slices-regexp.js
@@ -1,4 +1,4 @@
-// Copyright 2009 the V8 project authors. All rights reserved.
+// 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:
@@ -24,11 +24,6 @@
 // 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: --string-slices
-
-//assertEquals('345"12345 6"1234567"123',
-//             '12345""12345 6""1234567""1234'.slice(2,-1).replace(/""/g, '"'));
 
 var foo = "lsdfj sldkfj sdklfj læsdfjl sdkfjlsdk fjsdl fjsdljskdj flsj flsdkj flskd regexp: /foobar/\nldkfj sdlkfj sdkl";
 for(var i = 0; i < 1000; i++) {
diff --git a/test/mjsunit/string-slices.js b/test/mjsunit/string-slices.js
index 8cc1f81..3eb30f1 100755
--- a/test/mjsunit/string-slices.js
+++ b/test/mjsunit/string-slices.js
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// 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:
@@ -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: --string-slices --expose-externalize-string
+// Flags: --expose-externalize-string --allow-natives-syntax
 
 var s = 'abcdefghijklmn';
 assertEquals(s, s.substr());
@@ -100,14 +100,7 @@
 
 // Keep creating strings to to force allocation failure on substring creation.
 var x = "0123456789ABCDEF";
-x += x;  // 2^5
-x += x;
-x += x;
-x += x;
-x += x;
-x += x;  // 2^10
-x += x;
-x += x;
+for (var i = 0; i < 8; i++) x += x;
 var xl = x.length;
 var cache = [];
 for (var i = 0; i < 1000; i++) {
@@ -119,14 +112,7 @@
 
 // Same with two-byte strings
 var x = "\u2028123456789ABCDEF";
-x += x;  // 2^5
-x += x;
-x += x;
-x += x;
-x += x;
-x += x;  // 2^10
-x += x;
-x += x;
+for (var i = 0; i < 8; i++) x += x;
 var xl = x.length;
 var cache = [];
 for (var i = 0; i < 1000; i++) {
@@ -189,11 +175,34 @@
 assertEquals("\u03B2\u03B3\u03B4\u03B5\u03B4\u03B5\u03B6\u03B7",
     utf.substring(5,1) + utf.substring(3,7));
 
-/*
 // Externalizing strings.
-var a = "123456789qwertyuiopasdfghjklzxcvbnm";
-var b = a.slice(1,-1);
+var a = "123456789" + "qwertyuiopasdfghjklzxcvbnm";
+var b = "23456789qwertyuiopasdfghjklzxcvbn"
 assertEquals(a.slice(1,-1), b);
-externalizeString(a);
+
+assertTrue(isAsciiString(a));
+externalizeString(a, true);
+assertFalse(isAsciiString(a));
+
 assertEquals(a.slice(1,-1), b);
-*/
+assertTrue(/3456789qwe/.test(a));
+assertEquals(5, a.indexOf("678"));
+assertEquals("12345", a.split("6")[0]);
+
+// Create a slice with an external string as parent string.
+var c = a.slice(1,-1);
+
+function test_crankshaft() {
+  for (var i = 0; i < 20; i++) {
+    assertEquals(b.charAt(i), a.charAt(i + 1));
+    assertEquals(b.charAt(i), c.charAt(i));
+    assertEquals(b.charAt(4), c.charAt(4));
+    assertTrue(/3456789qwe/.test(c));
+    assertEquals(4, c.indexOf("678"));
+    assertEquals("2345", c.split("6")[0]);
+  }
+}
+
+test_crankshaft();
+%OptimizeFunctionOnNextCall(test_crankshaft);
+test_crankshaft();
\ No newline at end of file
diff --git a/test/mjsunit/switch.js b/test/mjsunit/switch.js
index 180f994..6a61fe5 100644
--- a/test/mjsunit/switch.js
+++ b/test/mjsunit/switch.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: --allow-natives-syntax
+
 function f0() {
   switch (0) {
     // switch deliberately left empty
@@ -126,6 +128,42 @@
 assertEquals(3, f4(2), "fallthrough-switch.2");
 assertEquals(5, f4(3), "fallthrough-switch.3");
 
+function f4_string(tag, x) {
+  switch(tag) {
+    case 'zero':
+      x++;
+    case 'two':
+      x++;
+  }
+  return x;
+}
+
+// Symbols
+assertEquals(2, f4_string('zero', 0), "fallthrough-string-switch.0");
+assertEquals(1, f4_string('one', 1), "fallthrough-string-switch.1");
+assertEquals(3, f4_string('two', 2), "fallthrough-string-switch.2");
+
+// Strings
+assertEquals(2, f4_string('_zero'.slice(1), 0), "fallthrough-string-switch.3");
+assertEquals(1, f4_string('_one'.slice(1), 1), "fallthrough-string-switch.4");
+assertEquals(3, f4_string('_two'.slice(1), 2), "fallthrough-string-switch.5");
+
+// Oddball
+assertEquals(3, f4_string(null, 3), "fallthrough-string-switch.6");
+
+// Test for regression
+function regress_string(value) {
+  var json = 1;
+  switch (typeof value) {
+    case 'object':
+      break;
+
+    default:
+
+  }
+  return json;
+};
+assertEquals(1, regress_string('object'), 'regression-string');
 
 function f5(x) {
   switch(x) {
@@ -287,3 +325,138 @@
 var verylong = makeVeryLong(verylong_size);
 
 assertEquals(verylong_size * 2 + 1, verylong());
+
+//
+// Test suite below aims to cover all possible combinations of following:
+//
+//  clauses  |   tags   |   type feedback   |  optimization
+// =========================================================
+//  strings  |  symbol  |     all           |      on
+//  smis     |  string  |     target        |      off
+//  mixed    |  oddball |     non-target    |
+//           |  smis    |     none          |
+//           |  heapnum |                   |
+// =========================================================
+
+// Function-with-switch generator
+var test_id = 0,
+    clause_values = {
+      string: ['abc', 'def', 'ghi', 'jkl'],
+      smi: [1, 2, 3, 4],
+      mixed: ['abc', 1, 'def', 2, 'ghi', 3, 'jkl', 4]
+    };
+
+function switch_gen(clause_type, feedback, optimize) {
+  var values = clause_values[clause_type];
+
+  function opt(fn) {
+    if (feedback === 'all') {
+      values.forEach(fn);
+    } else if (Array.isArray(feedback)) {
+      // Non-target
+      values.filter(function(v) {
+        return feedback.indexOf(v) === -1;
+      }).forEach(fn);
+    } else if (feedback !== undefined) {
+      // Target
+      fn(feedback);
+    } else {
+      // None
+    }
+
+    if (optimize) %OptimizeFunctionOnNextCall(fn);
+
+    return fn;
+  };
+
+  return opt(new Function(
+      'tag',
+      '"' + (test_id++) + '";' +
+      'switch(tag) {' +
+      values.map(function(value) {
+        return 'case ' + JSON.stringify(value) + ': return' +
+               JSON.stringify('ok-' + value);
+      }).join(';') +
+      '}'
+  ));
+};
+
+function test_switch(clause_type, test_type, feedback, optimize) {
+  var pairs = [],
+      fn = switch_gen(clause_type, feedback, optimize);
+
+  if (Array.isArray(test_type)) {
+    pairs = test_type.map(function(v) {
+      return {
+        value: v,
+        expected: 'ok-' + v
+      };
+    });
+  } else if (test_type === 'symbols') {
+    pairs = clause_values.string.map(function(v) {
+      return {
+        value: v,
+        expected: clause_type !== 'smi' ? 'ok-' + v : undefined
+      };
+    });
+  } else if (test_type === 'strings') {
+    pairs = clause_values.string.map(function(v) {
+      return {
+        value: ('%%' + v).slice(2),
+        expected: clause_type !== 'smi' ? 'ok-' + v : undefined
+      };
+    });
+  } else if (test_type === 'oddball') {
+    pairs = [
+      { value: null, expected: undefined },
+      { value: NaN, expected: undefined },
+      { value: undefined, expected: undefined }
+    ];
+  } else if (test_type === 'smi') {
+    pairs = clause_values.smi.map(function(v) {
+      return {
+        value: v,
+        expected: clause_type !== 'string' ? 'ok-' + v : undefined
+      };
+    });
+  } else if (test_type === 'heapnum') {
+    pairs = clause_values.smi.map(function(v) {
+      return {
+        value: ((v * 17)/16) - ((v*17)%16/16),
+        expected: clause_type !== 'string' ? 'ok-' + v : undefined
+      };
+    });
+  }
+
+  pairs.forEach(function(pair) {
+    assertEquals(fn(pair.value), pair.expected);
+  });
+};
+
+// test_switch(clause_type, test_type, feedback, optimize);
+
+function test_switches(opt) {
+  var test_types = ['symbols', 'strings', 'oddball', 'smi', 'heapnum'];
+
+  function test(clause_type) {
+    var values = clause_values[clause_type];
+
+    test_types.forEach(function(test_type) {
+      test_switch(clause_type, test_type, 'all', opt);
+      test_switch(clause_type, test_type, 'none', opt);
+
+      // Targeting specific clause feedback
+      values.forEach(function(value) {
+        test_switch(clause_type, test_type, [value], value, opt);
+        test_switch(clause_type, test_type, value, value, opt);
+      });
+    });
+  };
+
+  test('string');
+  test('smi');
+  test('mixed');
+};
+
+test_switches(false);
+test_switches(true);
diff --git a/test/mjsunit/to_number_order.js b/test/mjsunit/to_number_order.js
index d17e600..50e4bc7 100644
--- a/test/mjsunit/to_number_order.js
+++ b/test/mjsunit/to_number_order.js
@@ -161,7 +161,7 @@
 
 x = "";
 assertFalse(a > b, "Compare objects a > b");
-assertEquals("fiskhest", x, "Compare objects a > b valueOf order");
+assertEquals("hestfisk", x, "Compare objects a > b valueOf order");
 
 x = "";
 assertFalse(a > void(0), "Compare objects a > undefined");
@@ -195,7 +195,7 @@
 
   x = "";
   assertFalse(a > b, "Compare objects a > b");
-  assertEquals("fiskhest", x, "Compare objects a > b valueOf order");
+  assertEquals("hestfisk", x, "Compare objects a > b valueOf order");
 
   x = "";
   assertFalse(a > void(0), "Compare objects a > undefined");
diff --git a/test/mjsunit/unbox-double-arrays.js b/test/mjsunit/unbox-double-arrays.js
index feecaec..fd7db28 100644
--- a/test/mjsunit/unbox-double-arrays.js
+++ b/test/mjsunit/unbox-double-arrays.js
@@ -77,8 +77,6 @@
     assertEquals(value_6, a[6]);
     assertEquals(value_6, a[computed_6()]); // Test non-constant key
     assertEquals(value_7, a[7]);
-    assertEquals(undefined, a[large_array_size-1]);
-    assertEquals(undefined, a[-1]);
     assertEquals(large_array_size, a.length);
     assertTrue(%HasFastDoubleElements(a));
   }
@@ -89,8 +87,6 @@
     assertEquals(value_6, a[6]);
     assertEquals(value_6, a[computed_6()]); // Test non-constant key
     assertEquals(value_7, a[7]);
-    assertEquals(undefined, a[large_array_size-1]);
-    assertEquals(undefined, a[-1]);
     assertEquals(large_array_size, a.length);
     assertTrue(%HasFastDoubleElements(a));
   }
@@ -101,8 +97,6 @@
     assertEquals(value_6, a[6]);
     assertEquals(value_6, a[computed_6()]); // Test non-constant key
     assertEquals(value_7, a[7]);
-    assertEquals(undefined, a[large_array_size-1]);
-    assertEquals(undefined, a[-1]);
     assertEquals(large_array_size, a.length);
     assertTrue(%HasFastDoubleElements(a));
   }
@@ -113,20 +107,20 @@
     assertEquals(value_6, a[6]);
     assertEquals(value_6, a[computed_6()]); // Test non-constant key
     assertEquals(value_7, a[7]);
-    assertEquals(undefined, a[large_array_size-1]);
-    assertEquals(undefined, a[-1]);
     assertEquals(large_array_size, a.length);
     assertTrue(%HasFastDoubleElements(a));
   }
 
   function test_various_loads5(a, value_5, value_6, value_7) {
     assertTrue(%HasFastDoubleElements(a));
-    assertEquals(value_5, a[5]);
-    assertEquals(value_6, a[6]);
-    assertEquals(value_6, a[computed_6()]); // Test non-constant key
+    if (value_5 != undefined) {
+      assertEquals(value_5, a[5]);
+    };
+    if (value_6 != undefined) {
+      assertEquals(value_6, a[6]);
+      assertEquals(value_6, a[computed_6()]); // Test non-constant key
+    }
     assertEquals(value_7, a[7]);
-    assertEquals(undefined, a[large_array_size-1]);
-    assertEquals(undefined, a[-1]);
     assertEquals(large_array_size, a.length);
     assertTrue(%HasFastDoubleElements(a));
   }
@@ -137,8 +131,16 @@
     assertEquals(value_6, a[6]);
     assertEquals(value_6, a[computed_6()]); // Test non-constant key
     assertEquals(value_7, a[7]);
-    assertEquals(undefined, a[large_array_size-1]);
-    assertEquals(undefined, a[-1]);
+    assertEquals(large_array_size, a.length);
+    assertTrue(%HasFastDoubleElements(a));
+  }
+
+  function test_various_loads7(a, value_5, value_6, value_7) {
+    assertTrue(%HasFastDoubleElements(a));
+    assertEquals(value_5, a[5]);
+    assertEquals(value_6, a[6]);
+    assertEquals(value_6, a[computed_6()]); // Test non-constant key
+    assertEquals(value_7, a[7]);
     assertEquals(large_array_size, a.length);
     assertTrue(%HasFastDoubleElements(a));
   }
@@ -248,6 +250,8 @@
                       expected_array_value(7));
 
   // Make sure Crankshaft code handles the hole correctly (bailout)
+  var large_array = new allocator(large_array_size);
+  force_to_fast_double_array(large_array);
   test_various_stores(large_array,
                       expected_array_value(5),
                       expected_array_value(6),
@@ -273,7 +277,12 @@
                       undefined,
                       expected_array_value(7));
 
+  %DeoptimizeFunction(test_various_loads6);
+  gc();
+
   // Test stores for non-NaN.
+  var large_array = new allocator(large_array_size);
+  force_to_fast_double_array(large_array);
   %OptimizeFunctionOnNextCall(test_various_stores);
   test_various_stores(large_array,
                       expected_array_value(5),
@@ -285,7 +294,19 @@
                       expected_array_value(6),
                       expected_array_value(7));
 
-  test_various_loads6(large_array,
+  test_various_loads7(large_array,
+                      expected_array_value(5),
+                      expected_array_value(6),
+                      expected_array_value(7));
+
+  test_various_loads7(large_array,
+                      expected_array_value(5),
+                      expected_array_value(6),
+                      expected_array_value(7));
+
+  %OptimizeFunctionOnNextCall(test_various_loads7);
+
+  test_various_loads7(large_array,
                       expected_array_value(5),
                       expected_array_value(6),
                       expected_array_value(7));
@@ -301,7 +322,7 @@
                       -NaN,
                       expected_array_value(7));
 
-  test_various_loads6(large_array,
+  test_various_loads7(large_array,
                       NaN,
                       -NaN,
                       expected_array_value(7));
@@ -317,7 +338,7 @@
                       -Infinity,
                       expected_array_value(7));
 
-  test_various_loads6(large_array,
+  test_various_loads7(large_array,
                       Infinity,
                       -Infinity,
                       expected_array_value(7));
@@ -434,7 +455,6 @@
 large_array3[4] = -Infinity;
 
 function call_apply() {
-  assertTrue(%HasFastDoubleElements(large_array3));
   called_by_apply.apply({}, large_array3);
 }
 
@@ -449,7 +469,6 @@
 function test_for_in() {
   // Due to previous tests, keys 0..25 and 95 should be present.
   next_expected = 0;
-  assertTrue(%HasFastDoubleElements(large_array3));
   for (x in large_array3) {
     assertTrue(next_expected++ == x);
     if (next_expected == 25) {
diff --git a/test/mjsunit/undeletable-functions.js b/test/mjsunit/undeletable-functions.js
index 04fd060..635ea6f 100644
--- a/test/mjsunit/undeletable-functions.js
+++ b/test/mjsunit/undeletable-functions.js
@@ -25,11 +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.
 
-// Test that we match JSC in making some functions undeletable.
-// See http://code.google.com/p/chromium/issues/detail?id=1717
-// The functions on these prototypes are not just undeletable.  It is
-// possible to override them with new definitions, then get the old
-// version back by deleting the new definition.
+// Test that we match ECMAScript in making most builtin functions
+// deletable and only specific ones undeletable or read-only.
 
 var array;
 
@@ -37,7 +34,7 @@
   "toString", "toLocaleString", "join", "pop", "push", "concat", "reverse",
   "shift", "unshift", "slice", "splice", "sort", "filter", "forEach", "some",
   "every", "map", "indexOf", "lastIndexOf", "reduce", "reduceRight"];
-CheckJSCSemantics(Array.prototype, array, "Array prototype");
+CheckEcmaSemantics(Array.prototype, array, "Array prototype");
 
 var old_Array_prototype = Array.prototype;
 var new_Array_prototype = {};
@@ -57,12 +54,12 @@
   "setUTCMinutes", "setHours", "setUTCHours", "setDate", "setUTCDate",
   "setMonth", "setUTCMonth", "setFullYear", "setUTCFullYear", "toGMTString",
   "toUTCString", "getYear", "setYear", "toISOString", "toJSON"];
-CheckJSCSemantics(Date.prototype, array, "Date prototype");
+CheckEcmaSemantics(Date.prototype, array, "Date prototype");
 
 array = [
   "random", "abs", "acos", "asin", "atan", "ceil", "cos", "exp", "floor", "log",
   "round", "sin", "sqrt", "tan", "atan2", "pow", "max", "min"];
-CheckJSCSemantics(Math, array, "Math1");
+CheckEcmaSemantics(Math, array, "Math1");
 
 CheckEcmaSemantics(Date, ["UTC", "parse", "now"], "Date");
 
@@ -76,6 +73,8 @@
   "execScript"];
 CheckEcmaSemantics(this, array, "Global");
 CheckReadOnlyAttr(this, "Infinity");
+CheckReadOnlyAttr(this, "NaN");
+CheckReadOnlyAttr(this, "undefined");
 
 array = ["exec", "test", "toString", "compile"];
 CheckEcmaSemantics(RegExp.prototype, array, "RegExp prototype");
@@ -112,7 +111,7 @@
   "toUpperCase", "toLocaleUpperCase", "link", "anchor", "fontcolor", "fontsize",
   "big", "blink", "bold", "fixed", "italics", "small", "strike", "sub", "sup",
   "toJSON", "toString", "valueOf"];
-CheckJSCSemantics(String.prototype, array, "String prototype");
+CheckEcmaSemantics(String.prototype, array, "String prototype");
 CheckEcmaSemantics(String, ["fromCharCode"], "String");
 
 
@@ -124,14 +123,6 @@
 }
 
 
-function CheckJSCSemantics(type, props, name) {
-  print(name);
-  for (var i = 0; i < props.length; i++) {
-    CheckNotDeletable(type, props[i]);
-  }
-}
-
-
 function CheckDontDelete(type, props, name) {
   print(name);
   for (var i = 0; i < props.length; i++) {
@@ -154,21 +145,6 @@
 }
 
 
-function CheckNotDeletable(type, prop) {
-  var old = type[prop];
-  if (!type[prop]) return;
-  assertTrue(type.hasOwnProperty(prop), "inherited: " + prop);
-  var deleted = delete type[prop];
-  assertTrue(deleted, "delete operator returned false: " + prop);
-  assertTrue(type.hasOwnProperty(prop), "not there after delete: " + prop);
-  type[prop] = "foo";
-  assertEquals("foo", type[prop], "not overwritable: " + prop);
-  deleted = delete type[prop];
-  assertTrue(deleted, "delete operator returned false 2nd time: " + prop);
-  assertEquals(old.toString(), type[prop].toString(), "delete didn't restore the old value: " + prop);
-}
-
-
 function CheckDontDeleteAttr(type, prop) {
   var old = type[prop];
   if (!type[prop]) return;
@@ -189,7 +165,7 @@
   assertFalse(deleted, "delete operator returned true: " + prop);
   assertTrue(type.hasOwnProperty(prop), "not there after delete: " + prop);
   type[prop] = "foo";
-  assertEquals("foo", type[prop], "overwritable: " + prop);
+  assertEquals(old, type[prop], "overwritable: " + prop);
 }
 
 print("OK");