Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / v8 / test / mjsunit / harmony / super.js
index 89fb4b1..d972407 100644 (file)
@@ -18,6 +18,8 @@
 
   function fDerived() {
      assertEquals("Base this is Derived", super.f());
+     var a = super.x;
+     assertEquals(15, a);
      assertEquals(15, super.x);
      assertEquals(27, this.x);
 
   assertEquals("Derived", new Derived().f());
 }());
 
+
+(function TestSuperKeyedLoads() {
+  var x = 'x';
+  var derivedDataProperty = 'derivedDataProperty';
+  var f = 'f';
+  function Base() { }
+  function Derived() {
+    this[derivedDataProperty] = 'xxx';
+  }
+  Derived.prototype = Object.create(Base.prototype);
+
+  function fBase() { return "Base " + this.toString(); }
+
+  Base.prototype[f] = fBase.toMethod(Base.prototype);
+
+  function fDerived() {
+     assertEquals("Base this is Derived", super[f]());
+     var a = super[x];
+     assertEquals(15, a);
+     assertEquals(15, super[x]);
+     assertEquals(27, this[x]);
+
+     return "Derived"
+  }
+
+  Base.prototype[x] = 15;
+  Base.prototype.toString = function() { return "this is Base"; };
+  Derived.prototype.toString = function() { return "this is Derived"; };
+  Derived.prototype[x] = 27;
+  Derived.prototype[f] = fDerived.toMethod(Derived.prototype);
+
+  assertEquals("Base this is Base", new Base().f());
+  assertEquals("Derived", new Derived().f());
+}());
+
+
+(function TestSuperNumericKeyedLoads() {
+  var x = 1;
+  var derivedDataProperty = 2;
+  var f = 3;
+  function Base() { }
+  function Derived() {
+    this[derivedDataProperty] = 'xxx';
+  }
+  Derived.prototype = Object.create(Base.prototype);
+
+  function fBase() { return "Base " + this.toString(); }
+
+  Base.prototype[f] = fBase.toMethod(Base.prototype);
+
+  function fDerived() {
+     assertEquals("Base this is Derived", super[f]());
+     var a = super[x];
+     assertEquals(15, a);
+     assertEquals(15, super[x]);
+     assertEquals(27, this[x]);
+
+     return "Derived"
+  }
+
+  Base.prototype[x] = 15;
+  Base.prototype.toString = function() { return "this is Base"; };
+  Derived.prototype.toString = function() { return "this is Derived"; };
+  Derived.prototype[x] = 27;
+  Derived.prototype[f] = fDerived.toMethod(Derived.prototype);
+
+  assertEquals("Base this is Base", new Base()[f]());
+  assertEquals("Derived", new Derived()[f]());
+}());
+
+
 (function TestSuperKeywordNonMethod() {
   function f() {
     super.unknown();
   Derived.prototype.testGetter = function() {
     return super.x;
   }.toMethod(Derived.prototype);
+  Derived.prototype.testGetterStrict = function() {
+    'use strict';
+    return super.x;
+  }.toMethod(Derived.prototype);
+  derived = new Derived();
+  assertEquals('derived', derived.testGetter());
+  derived = new Derived();
+  assertEquals('derived', derived.testGetterStrict());
+}());
+
+
+(function TestGetterKeyed() {
+  var x = 'x';
+  function Base() {}
+  var derived;
+  Base.prototype = {
+    constructor: Base,
+    get x() {
+      assertSame(this, derived);
+      return this._x;
+    },
+    _x: 'base'
+  };
+
+  function Derived() {}
+  Derived.__proto__ = Base;
+  Derived.prototype = {
+    __proto__: Base.prototype,
+    constructor: Derived,
+    _x: 'derived'
+  };
+  Derived.prototype.testGetter = function() {
+    return super[x];
+  }.toMethod(Derived.prototype);
+  Derived.prototype.testGetterStrict = function() {
+    'use strict';
+    return super[x];
+  }.toMethod(Derived.prototype);
+  Derived.prototype.testGetterWithToString = function() {
+    var toStringCalled;
+    var o = { toString: function() {
+      toStringCalled++;
+      return 'x';
+    } };
+
+    toStringCalled = 0;
+    assertEquals('derived', super[o]);
+    assertEquals(1, toStringCalled);
+
+    var eToThrow = new Error();
+    var oThrowsInToString = { toString: function() {
+      throw eToThrow;
+    } };
+
+    var ex = null;
+    try {
+      super[oThrowsInToString];
+    } catch(e) { ex = e }
+    assertEquals(eToThrow, ex);
+
+    var oReturnsNumericString = { toString: function() {
+      return "1";
+    } };
+
+    assertEquals(undefined, super[oReturnsNumericString]);
+    assertEquals(undefined, super[1]);
+  }.toMethod(Derived.prototype);
+  derived = new Derived();
+  assertEquals('derived', derived.testGetter());
+  derived = new Derived();
+  assertEquals('derived', derived.testGetterStrict());
+  derived = new Derived();
+  derived.testGetterWithToString();
+}());
+
+
+(function TestGetterNumericKeyed() {
+  var x = 42;
+  function Base() {}
+  var derived;
+  Base.prototype = {
+    constructor: Base,
+    _x: 'base'
+  };
+
+  Object.defineProperty(Base.prototype, x, { get: function() {
+      assertSame(this, derived);
+      return this._x;
+  }});
+
+  function Derived() {}
+  Derived.__proto__ = Base;
+  Derived.prototype = {
+    __proto__: Base.prototype,
+    constructor: Derived,
+    _x: 'derived'
+  };
+  Derived.prototype.testGetter = function() {
+    return super[x];
+  }.toMethod(Derived.prototype);
+  Derived.prototype.testGetterStrict = function() {
+    'use strict';
+    return super[x];
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.testGetterWithToString = function() {
+    var toStringCalled;
+    var o = { toString: function() {
+      toStringCalled++;
+      return '42';
+    } };
+
+    toStringCalled = 0;
+    assertEquals('derived', super[o]);
+    assertEquals(1, toStringCalled);
+
+    var eToThrow = new Error();
+    var oThrowsInToString = { toString: function() {
+      throw eToThrow;
+    } };
+
+    var ex = null;
+    try {
+      super[oThrowsInToString];
+    } catch(e) { ex = e }
+    assertEquals(eToThrow, ex);
+
+    var oReturnsNumericString = { toString: function() {
+      return "42";
+    } };
+
+    assertEquals('derived', super[oReturnsNumericString]);
+    assertEquals('derived', super[42]);
+  }.toMethod(Derived.prototype);
   derived = new Derived();
   assertEquals('derived', derived.testGetter());
+  derived = new Derived();
+  assertEquals('derived', derived.testGetterStrict());
+  derived = new Derived();
+  derived.testGetterWithToString();
 }());
 
-/*
- * TODO[dslomov]: named stores and keyed loads/stores not implemented yet.
+
 (function TestSetter() {
   function Base() {}
   Base.prototype = {
     _x: 'derived'
   };
   Derived.prototype.testSetter = function() {
-      super.x = 'foobar';
-    }.toMethod(Derived.prototype);
+    assertEquals('foobar', super.x = 'foobar');
+    assertEquals('foobarabc', super.x += 'abc');
+  }.toMethod(Derived.prototype);
   var d = new Derived();
   d.testSetter();
   assertEquals('base', Base.prototype._x);
-  assertEquals('foobar', d._x);
+  assertEquals('foobarabc', d._x);
+  d._x = '';
+  Derived.prototype.testSetterStrict = function() {
+    'use strict';
+    assertEquals('foobar', super.x = 'foobar');
+    assertEquals('foobarabc', super.x += 'abc');
+  }.toMethod(Derived.prototype);
+  d.testSetterStrict();
+  assertEquals('base', Base.prototype._x);
+  assertEquals('foobarabc', d._x);
 }());
 
 
-(function TestKeyedGetter() {
+(function TestSetterNumericKeyed() {
+  var x = 42;
   function Base() {}
   Base.prototype = {
     constructor: Base,
     _x: 'base'
   };
 
-  Object.defineProperty(Base.prototype, '0',
-        { get: function() { return this._x; } });
+  Object.defineProperty(Base.prototype, x,
+    { get: function() { return this._x; },
+      set: function(v) { this._x = v; }
+    });
 
   function Derived() {}
   Derived.__proto__ = Base;
     constructor: Derived,
     _x: 'derived'
   };
-  Derived.prototype.testGetter = function() {
-      return super[0];
-    }.toMethod(Derived.prototype);
-  assertEquals('derived', new Derived()[0]);
-  // assertEquals('derived', new Derived().testGetter());
+  Derived.prototype.testSetter = function() {
+    assertEquals('foobar', super[x] = 'foobar');
+    assertEquals('foobarabc', super[x] += 'abc');
+  }.toMethod(Derived.prototype);
+  var d = new Derived();
+  d.testSetter();
+  assertEquals('base', Base.prototype._x);
+  assertEquals('foobarabc', d._x);
+  d._x = '';
+  Derived.prototype.testSetterStrict = function() {
+    'use strict';
+    assertEquals('foobar', super[x] = 'foobar');
+    assertEquals('foobarabc', super[x] += 'abc');
+  }.toMethod(Derived.prototype);
+  d.testSetterStrict();
+  assertEquals('base', Base.prototype._x);
+  assertEquals('foobarabc', d._x);
+
+
+  Derived.prototype.testSetterWithToString = function() {
+    var toStringCalled;
+    var o = { toString: function() {
+      toStringCalled++;
+      return x;
+    } };
+
+    toStringCalled = 0;
+    super[o] = 'set';
+    assertEquals(1, toStringCalled);
+    assertEquals('set', this._x);
+
+    var eToThrow = new Error();
+    var oThrowsInToString = { toString: function() {
+      throw eToThrow;
+    } };
+
+    var ex = null;
+    try {
+      super[oThrowsInToString] = 'xyz';
+    } catch(e) { ex = e }
+    assertEquals(eToThrow, ex);
+    assertEquals('set', this._x);
+  }.toMethod(Derived.prototype);
+  d = new Derived();
+  d.testSetterWithToString();
+}());
+
+
+(function TestSetterKeyed() {
+  var x = 'x';
+  function Base() {}
+  Base.prototype = {
+    constructor: Base,
+    get x() {
+      return this._x;
+    },
+    set x(v) {
+      this._x = v;
+    },
+    _x: 'base'
+  };
+
+  function Derived() {}
+  Derived.__proto__ = Base;
+  Derived.prototype = {
+    __proto__: Base.prototype,
+    constructor: Derived,
+    _x: 'derived'
+  };
+  Derived.prototype.testSetter = function() {
+    assertEquals('foobar', super[x] = 'foobar');
+    assertEquals('foobarabc', super[x] += 'abc');
+  }.toMethod(Derived.prototype);
+  var d = new Derived();
+  d.testSetter();
+  assertEquals('base', Base.prototype._x);
+  assertEquals('foobarabc', d._x);
+  d._x = '';
+  Derived.prototype.testSetterStrict = function() {
+    'use strict';
+    assertEquals('foobar', super[x] = 'foobar');
+    assertEquals('foobarabc', super[x] += 'abc');
+  }.toMethod(Derived.prototype);
+  d.testSetterStrict();
+  assertEquals('base', Base.prototype._x);
+  assertEquals('foobarabc', d._x);
+
+
+  Derived.prototype.testSetterWithToString = function() {
+    var toStringCalled;
+    var o = { toString: function() {
+      toStringCalled++;
+      return 'x';
+    } };
+
+    toStringCalled = 0;
+    super[o] = 'set';
+    assertEquals(1, toStringCalled);
+    assertEquals('set', this._x);
+
+    var eToThrow = new Error();
+    var oThrowsInToString = { toString: function() {
+      throw eToThrow;
+    } };
+
+    var ex = null;
+    try {
+      super[oThrowsInToString] = 'xyz';
+    } catch(e) { ex = e }
+    assertEquals(eToThrow, ex);
+    assertEquals('set', this._x);
+
+    var oReturnsNumericString = { toString: function() {
+      return "1";
+    } };
+
+    assertEquals('abc', super[oReturnsNumericString] = 'abc');
+
+    assertEquals('set', this._x);
+
+    assertEquals(10,  super[1] = 10);
+  }.toMethod(Derived.prototype);
+  d = new Derived();
+  d.testSetterWithToString();
+}());
+
+
+(function TestSetterDataProperties() {
+  function Base() {}
+  Base.prototype = {
+    constructor: Base,
+    x: 'x from Base'
+  };
+
+  function Derived() {}
+  Derived.prototype = {
+    __proto__: Base.prototype,
+    constructor: Derived,
+  };
+
+  Derived.prototype.testSetter = function() {
+    assertEquals('x from Base', super.x);
+    super.x = 'data property';
+    assertEquals('x from Base', super.x);
+    assertEquals('data property', this.x);
+  }.toMethod(Derived.prototype);
+
+  new Derived().testSetter();
+}());
+
+
+(function TestKeyedSetterDataProperties() {
+  var x = 'x';
+  function Base() {}
+  Base.prototype = {
+    constructor: Base,
+    x: 'x from Base'
+  };
+
+  function Derived() {}
+  Derived.prototype = {
+    __proto__: Base.prototype,
+    constructor: Derived,
+  };
+
+  Derived.prototype.testSetter = function() {
+    assertEquals('x from Base', super[x]);
+    super[x] = 'data property';
+    assertEquals('x from Base', super[x]);
+    assertEquals('data property', this[x]);
+  }.toMethod(Derived.prototype);
+
+  new Derived().testSetter();
+}());
+
+
+(function TestKeyedNumericSetterDataProperties() {
+  var x = 42;
+  function Base() {}
+  Base.prototype = {
+    constructor: Base,
+    42: 'x from Base'
+  };
+
+  function Derived() {}
+  Derived.prototype = {
+    __proto__: Base.prototype,
+    constructor: Derived,
+  };
+
+  Derived.prototype.testSetter = function() {
+    assertEquals('x from Base', super[x]);
+    super[x] = 'data property';
+    assertEquals('x from Base', super[x]);
+    assertEquals('data property', this[x]);
+  }.toMethod(Derived.prototype);
+
+  new Derived().testSetter();
+}());
+
+
+(function TestAccessorsOnPrimitives() {
+  var getCalled = 0;
+  var setCalled = 0;
+  function Base() {}
+  Base.prototype = {
+    constructor: Base,
+    get x() {
+      getCalled++;
+      return 1;
+    },
+    set x(v) {
+      setCalled++;
+      return v;
+    },
+  };
+
+  function Derived() {}
+  Derived.prototype = {
+    __proto__: Base.prototype,
+    constructor: Derived,
+  };
+  Derived.prototype.testSetter = function() {
+    setCalled = 0;
+    getCalled = 0;
+    assertEquals('object', typeof this);
+    assertTrue(this instanceof Number)
+    assertEquals(42, this.valueOf());
+    assertEquals(1, super.x);
+    assertEquals(1, getCalled);
+    assertEquals(0, setCalled);
+
+    assertEquals(5, super.x = 5);
+    assertEquals(1, getCalled);
+    assertEquals(1, setCalled);
+
+    assertEquals(6, super.x += 5);
+    assertEquals(2, getCalled);
+    assertEquals(2, setCalled);
+
+    super.newProperty = 15;
+    assertEquals(15, this.newProperty);
+    assertEquals(undefined, super.newProperty);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.testSetterStrict = function() {
+    'use strict';
+    getCalled = 0;
+    setCalled = 0;
+    assertTrue(42 === this);
+
+    assertEquals(1, super.x);
+    assertEquals(1, getCalled);
+    assertEquals(0, setCalled);
+
+    assertEquals(5, super.x = 5);
+    assertEquals(1, getCalled);
+    assertEquals(1, setCalled);
+
+    assertEquals(6, super.x += 5);
+    assertEquals(2, getCalled);
+    assertEquals(2, setCalled);
+
+    var ex;
+    try {
+      super.newProperty = 15;
+    } catch (e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.testSetter.call(42);
+  Derived.prototype.testSetterStrict.call(42);
+
+  function DerivedFromString() {}
+  DerivedFromString.prototype = Object.create(String.prototype);
+
+  function f() {
+    'use strict';
+    assertTrue(42 === this);
+    assertEquals(String.prototype.toString, super.toString);
+    var ex;
+    try {
+      super.toString();
+    } catch(e) { ex = e; }
+
+    assertTrue(ex instanceof TypeError);
+  }
+  f.toMethod(DerivedFromString.prototype).call(42);
+}());
+
+
+(function TestKeyedAccessorsOnPrimitives() {
+  var x = 'x';
+  var newProperty = 'newProperty';
+  var toString = 'toString';
+  var getCalled = 0;
+  var setCalled = 0;
+  function Base() {}
+  Base.prototype = {
+    constructor: Base,
+    get x() {
+      getCalled++;
+      return 1;
+    },
+    set x(v) {
+      setCalled++;
+      return v;
+    },
+  };
+
+  function Derived() {}
+  Derived.prototype = {
+    __proto__: Base.prototype,
+    constructor: Derived,
+  };
+  Derived.prototype.testSetter = function() {
+    setCalled = 0;
+    getCalled = 0;
+    assertEquals('object', typeof this);
+    assertTrue(this instanceof Number)
+    assertEquals(42, this.valueOf());
+    assertEquals(1, super[x]);
+    assertEquals(1, getCalled);
+    assertEquals(0, setCalled);
+
+    assertEquals(5, super[x] = 5);
+    assertEquals(1, getCalled);
+    assertEquals(1, setCalled);
+
+    assertEquals(6, super[x] += 5);
+    assertEquals(2, getCalled);
+    assertEquals(2, setCalled);
+
+    super[newProperty] = 15;
+    assertEquals(15, this[newProperty]);
+    assertEquals(undefined, super[newProperty]);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.testSetterStrict = function() {
+    'use strict';
+    getCalled = 0;
+    setCalled = 0;
+    assertTrue(42 === this);
+
+    assertEquals(1, super[x]);
+    assertEquals(1, getCalled);
+    assertEquals(0, setCalled);
+
+    assertEquals(5, super[x] = 5);
+    assertEquals(1, getCalled);
+    assertEquals(1, setCalled);
+
+    assertEquals(6, super[x] += 5);
+    assertEquals(2, getCalled);
+    assertEquals(2, setCalled);
+
+    var ex;
+    try {
+      super[newProperty] = 15;
+    } catch (e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.testSetter.call(42);
+  Derived.prototype.testSetterStrict.call(42);
+
+  function DerivedFromString() {}
+  DerivedFromString.prototype = Object.create(String.prototype);
+
+  function f() {
+    'use strict';
+    assertTrue(42 === this);
+    assertEquals(String.prototype.toString, super[toString]);
+    var ex;
+    try {
+      super[toString]();
+    } catch(e) { ex = e; }
+
+    assertTrue(ex instanceof TypeError);
+  }
+  f.toMethod(DerivedFromString.prototype).call(42);
+}());
+
+
+(function TestNumericKeyedAccessorsOnPrimitives() {
+  var x = 42;
+  var newProperty = 43;
+  var getCalled = 0;
+  var setCalled = 0;
+  function Base() {}
+  Base.prototype = {
+    constructor: Base,
+  };
+
+  Object.defineProperty(Base.prototype, x, {
+    get: function() {
+      getCalled++;
+      return 1;
+    },
+    set: function(v) {
+      setCalled++;
+      return v;
+    }
+  });
+
+  function Derived() {}
+  Derived.prototype = {
+    __proto__: Base.prototype,
+    constructor: Derived,
+  };
+  Derived.prototype.testSetter = function() {
+    setCalled = 0;
+    getCalled = 0;
+    assertEquals('object', typeof this);
+    assertTrue(this instanceof Number)
+    assertEquals(42, this.valueOf());
+    assertEquals(1, super[x]);
+    assertEquals(1, getCalled);
+    assertEquals(0, setCalled);
+
+    assertEquals(5, super[x] = 5);
+    assertEquals(1, getCalled);
+    assertEquals(1, setCalled);
+
+    assertEquals(6, super[x] += 5);
+    assertEquals(2, getCalled);
+    assertEquals(2, setCalled);
+
+    super[newProperty] = 15;
+    assertEquals(15, this[newProperty]);
+    assertEquals(undefined, super[newProperty]);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.testSetterStrict = function() {
+    'use strict';
+    getCalled = 0;
+    setCalled = 0;
+    assertTrue(42 === this);
+
+    assertEquals(1, super[x]);
+    assertEquals(1, getCalled);
+    assertEquals(0, setCalled);
+
+    assertEquals(5, super[x] = 5);
+    assertEquals(1, getCalled);
+    assertEquals(1, setCalled);
+
+    assertEquals(6, super[x] += 5);
+    assertEquals(2, getCalled);
+    assertEquals(2, setCalled);
+
+    var ex;
+    try {
+      super[newProperty] = 15;
+    } catch (e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.testSetter.call(42);
+  Derived.prototype.testSetterStrict.call(42);
+}());
+
+
+(function TestKeyedNumericSetterOnExotics() {
+  function Base() {}
+  function Derived() {}
+  Derived.prototype = { __proto__: Base.prototype };
+
+  Derived.prototype.callSetterOnArray = function() {
+    super[42] = 1;
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.callStrictSetterOnString = function() {
+    'use strict';
+    assertEquals('string', typeof this);
+    assertTrue('abcdef' === this);
+    var ex = null;
+    try {
+      super[5] = 'q';
+    } catch(e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+
+    ex = null;
+    try {
+      super[1024] = 'q';
+    } catch(e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+  }.toMethod(Derived.prototype);
+
+  var x = [];
+  assertEquals(0, x.length);
+  Derived.prototype.callSetterOnArray.call(x);
+  assertEquals(43, x.length);
+  assertEquals(1, x[42]);
+
+  var s = 'abcdef';
+  Derived.prototype.callStrictSetterOnString.call(s)
+}());
+
+
+(function TestSetterUndefinedProperties() {
+  function Base() {}
+  function Derived() {}
+  Derived.prototype = { __proto__ : Base.prototype };
+  Derived.prototype.mSloppy = function () {
+    assertEquals(undefined, super.x);
+    assertEquals(undefined, this.x);
+    super.x = 10;
+    assertEquals(10, this.x);
+    assertEquals(undefined, super.x);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.mStrict = function () {
+    'use strict';
+    assertEquals(undefined, super.x);
+    assertEquals(undefined, this.x);
+    super.x = 10;
+    assertEquals(10, this.x);
+    assertEquals(undefined, super.x);
+  }.toMethod(Derived.prototype);
+  var d = new Derived();
+  d.mSloppy();
+  assertEquals(10, d.x);
+  var d1 = new Derived();
+  d1.mStrict();
+  assertEquals(10, d.x);
+}());
+
+
+(function TestKeyedSetterUndefinedProperties() {
+  var x = 'x';
+  function Base() {}
+  function Derived() {}
+  Derived.prototype = { __proto__ : Base.prototype };
+  Derived.prototype.mSloppy = function () {
+    assertEquals(undefined, super[x]);
+    assertEquals(undefined, this[x]);
+    super[x] = 10;
+    assertEquals(10, this[x]);
+    assertEquals(undefined, super[x]);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.mStrict = function () {
+    'use strict';
+    assertEquals(undefined, super[x]);
+    assertEquals(undefined, this[x]);
+    super[x] = 10;
+    assertEquals(10, this[x]);
+    assertEquals(undefined, super[x]);
+  }.toMethod(Derived.prototype);
+  var d = new Derived();
+  d.mSloppy();
+  assertEquals(10, d.x);
+  var d1 = new Derived();
+  d1.mStrict();
+  assertEquals(10, d.x);
+}());
+
+
+(function TestKeyedNumericSetterUndefinedProperties() {
+  var x = 42;
+  function Base() {}
+  function Derived() {}
+  Derived.prototype = { __proto__ : Base.prototype };
+  Derived.prototype.mSloppy = function () {
+    assertEquals(undefined, super[x]);
+    assertEquals(undefined, this[x]);
+    super[x] = 10;
+    assertEquals(10, this[x]);
+    assertEquals(undefined, super[x]);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.mStrict = function () {
+    'use strict';
+    assertEquals(undefined, super[x]);
+    assertEquals(undefined, this[x]);
+    super[x] = 10;
+    assertEquals(10, this[x]);
+    assertEquals(undefined, super[x]);
+  }.toMethod(Derived.prototype);
+  var d = new Derived();
+  d.mSloppy();
+  assertEquals(10, d[x]);
+  var d1 = new Derived();
+  d1.mStrict();
+  assertEquals(10, d[x]);
+}());
+
+
+(function TestSetterCreatingOwnProperties() {
+  function Base() {}
+  function Derived() {}
+  Derived.prototype = { __proto__ : Base.prototype };
+  var setterCalled;
+
+  Derived.prototype.mSloppy = function() {
+    assertEquals(42, this.ownReadOnly);
+    super.ownReadOnly = 55;
+    assertEquals(42, this.ownReadOnly);
+
+    assertEquals(15, this.ownReadonlyAccessor);
+    super.ownReadonlyAccessor = 55;
+    assertEquals(15, this.ownReadonlyAccessor);
+
+    setterCalled = 0;
+    super.ownSetter = 42;
+    assertEquals(1, setterCalled);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.mStrict = function() {
+    'use strict';
+    assertEquals(42, this.ownReadOnly);
+    var ex;
+    try {
+      super.ownReadOnly = 55;
+    } catch(e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+    assertEquals(42, this.ownReadOnly);
+
+    assertEquals(15, this.ownReadonlyAccessor);
+    ex = null;
+    try {
+      super.ownReadonlyAccessor = 55;
+    } catch(e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+    assertEquals(15, this.ownReadonlyAccessor);
+
+    setterCalled = 0;
+    super.ownSetter = 42;
+    assertEquals(1, setterCalled);
+  }.toMethod(Derived.prototype);
+
+  var d = new Derived();
+  Object.defineProperty(d, 'ownReadOnly', { value : 42, writable : false });
+  Object.defineProperty(d, 'ownSetter',
+      { set : function() { setterCalled++; } });
+  Object.defineProperty(d, 'ownReadonlyAccessor',
+      { get : function() { return 15; }});
+  d.mSloppy();
+  d.mStrict();
+}());
+
+
+(function TestSetterInForIn() {
+  var setCalled = 0;
+  var getCalled = 0;
+  function Base() {}
+  Base.prototype = {
+    constructor: Base,
+    get x() {
+      getCalled++;
+      return 1;
+    },
+    set x(v) {
+      setCalled++;
+      this.x_.push(v);
+    },
+  };
+
+  function Derived() {
+    this.x_ = [];
+  }
+  Derived.prototype = {
+    __proto__: Base.prototype,
+    constructor: Derived,
+  };
+
+  Derived.prototype.testIter = function() {
+    setCalled = 0;
+    getCalled = 0;
+    for (super.x in [1,2,3]) {}
+    assertEquals(0, getCalled);
+    assertEquals(3, setCalled);
+    assertEquals(["0","1","2"], this.x_);
+  }.toMethod(Derived.prototype);
+
+  new Derived().testIter();
+
+  var x = 'x';
+  Derived.prototype.testIterKeyed = function() {
+    setCalled = 0;
+    getCalled = 0;
+    for (super[x] in [1,2,3]) {}
+    assertEquals(0, getCalled);
+    assertEquals(3, setCalled);
+    assertEquals(["0","1","2"], this.x_);
+
+    this.x_ = [];
+    setCalled = 0;
+    getCalled = 0;
+    var toStringCalled = 0;
+    var o = {toString: function () { toStringCalled++; return x }};
+    for (super[o] in [1,2,3]) {}
+    assertEquals(0, getCalled);
+    assertEquals(3, setCalled);
+    assertEquals(3, toStringCalled);
+    assertEquals(["0","1","2"], this.x_);
+  }.toMethod(Derived.prototype);
+
+  new Derived().testIterKeyed();
+}());
+
+
+(function TestKeyedSetterCreatingOwnProperties() {
+  var ownReadOnly = 'ownReadOnly';
+  var ownReadonlyAccessor = 'ownReadonlyAccessor';
+  var ownSetter = 'ownSetter';
+  function Base() {}
+  function Derived() {}
+  Derived.prototype = { __proto__ : Base.prototype };
+  var setterCalled;
+
+  Derived.prototype.mSloppy = function() {
+    assertEquals(42, this[ownReadOnly]);
+    super[ownReadOnly] = 55;
+    assertEquals(42, this[ownReadOnly]);
+
+    assertEquals(15, this[ownReadonlyAccessor]);
+    super[ownReadonlyAccessor] = 55;
+    assertEquals(15, this[ownReadonlyAccessor]);
+
+    setterCalled = 0;
+    super[ownSetter] = 42;
+    assertEquals(1, setterCalled);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.mStrict = function() {
+    'use strict';
+    assertEquals(42, this[ownReadOnly]);
+    var ex;
+    try {
+      super[ownReadOnly] = 55;
+    } catch(e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+    assertEquals(42, this[ownReadOnly]);
+
+    assertEquals(15, this[ownReadonlyAccessor]);
+    ex = null;
+    try {
+      super[ownReadonlyAccessor] = 55;
+    } catch(e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+    assertEquals(15, this[ownReadonlyAccessor]);
+
+    setterCalled = 0;
+    super[ownSetter] = 42;
+    assertEquals(1, setterCalled);
+  }.toMethod(Derived.prototype);
+
+  var d = new Derived();
+  Object.defineProperty(d, 'ownReadOnly', { value : 42, writable : false });
+  Object.defineProperty(d, 'ownSetter',
+      { set : function() { setterCalled++; } });
+  Object.defineProperty(d, 'ownReadonlyAccessor',
+      { get : function() { return 15; }});
+  d.mSloppy();
+  d.mStrict();
+}());
+
+
+(function TestKeyedNumericSetterCreatingOwnProperties() {
+  var ownReadOnly = 42;
+  var ownReadonlyAccessor = 43;
+  var ownSetter = 44;
+  function Base() {}
+  function Derived() {}
+  Derived.prototype = { __proto__ : Base.prototype };
+  var setterCalled;
+
+  Derived.prototype.mSloppy = function() {
+    assertEquals(42, this[ownReadOnly]);
+    super[ownReadOnly] = 55;
+    assertEquals(42, this[ownReadOnly]);
+
+    assertEquals(15, this[ownReadonlyAccessor]);
+    super[ownReadonlyAccessor] = 55;
+    assertEquals(15, this[ownReadonlyAccessor]);
+
+    setterCalled = 0;
+    super[ownSetter] = 42;
+    assertEquals(1, setterCalled);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.mStrict = function() {
+    'use strict';
+    assertEquals(42, this[ownReadOnly]);
+    var ex;
+    try {
+      super[ownReadOnly] = 55;
+    } catch(e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+    assertEquals(42, this[ownReadOnly]);
+
+    assertEquals(15, this[ownReadonlyAccessor]);
+    ex = null;
+    try {
+      super[ownReadonlyAccessor] = 55;
+    } catch(e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+    assertEquals(15, this[ownReadonlyAccessor]);
+
+    setterCalled = 0;
+    super[ownSetter] = 42;
+    assertEquals(1, setterCalled);
+  }.toMethod(Derived.prototype);
+
+  var d = new Derived();
+  Object.defineProperty(d, ownReadOnly, { value : 42, writable : false });
+  Object.defineProperty(d, ownSetter,
+      { set : function() { setterCalled++; } });
+  Object.defineProperty(d, ownReadonlyAccessor,
+      { get : function() { return 15; }});
+  d.mSloppy();
+  d.mStrict();
+}());
+
+
+(function TestSetterNoProtoWalk() {
+  function Base() {}
+  function Derived() {}
+  var getCalled;
+  var setCalled;
+  Derived.prototype = {
+    __proto__ : Base.prototype,
+    get x() { getCalled++; return 42; },
+    set x(v) { setCalled++; }
+  };
+
+  Derived.prototype.mSloppy = function() {
+    setCalled = 0;
+    getCalled = 0;
+    assertEquals(42, this.x);
+    assertEquals(1, getCalled);
+    assertEquals(0, setCalled);
+
+    getCalled = 0;
+    setCalled = 0;
+    this.x = 43;
+    assertEquals(0, getCalled);
+    assertEquals(1, setCalled);
+
+    getCalled = 0;
+    setCalled = 0;
+    super.x = 15;
+    assertEquals(0, setCalled);
+    assertEquals(0, getCalled);
+
+    assertEquals(15, this.x);
+    assertEquals(0, getCalled);
+    assertEquals(0, setCalled);
+
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.mStrict = function() {
+    'use strict';
+    setCalled = 0;
+    getCalled = 0;
+    assertEquals(42, this.x);
+    assertEquals(1, getCalled);
+    assertEquals(0, setCalled);
+
+    getCalled = 0;
+    setCalled = 0;
+    this.x = 43;
+    assertEquals(0, getCalled);
+    assertEquals(1, setCalled);
+
+    getCalled = 0;
+    setCalled = 0;
+    super.x = 15;
+    assertEquals(0, setCalled);
+    assertEquals(0, getCalled);
+
+    assertEquals(15, this.x);
+    assertEquals(0, getCalled);
+    assertEquals(0, setCalled);
+
+  }.toMethod(Derived.prototype);
+
+  new Derived().mSloppy();
+  new Derived().mStrict();
+}());
+
+
+(function TestKeyedSetterNoProtoWalk() {
+  var x = 'x';
+  function Base() {}
+  function Derived() {}
+  var getCalled;
+  var setCalled;
+  Derived.prototype = {
+    __proto__ : Base.prototype,
+    get x() { getCalled++; return 42; },
+    set x(v) { setCalled++; }
+  };
+
+  Derived.prototype.mSloppy = function() {
+    setCalled = 0;
+    getCalled = 0;
+    assertEquals(42, this[x]);
+    assertEquals(1, getCalled);
+    assertEquals(0, setCalled);
+
+    getCalled = 0;
+    setCalled = 0;
+    this[x] = 43;
+    assertEquals(0, getCalled);
+    assertEquals(1, setCalled);
+
+    getCalled = 0;
+    setCalled = 0;
+    super[x] = 15;
+    assertEquals(0, setCalled);
+    assertEquals(0, getCalled);
+
+    assertEquals(15, this[x]);
+    assertEquals(0, getCalled);
+    assertEquals(0, setCalled);
+
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.mStrict = function() {
+    'use strict';
+    setCalled = 0;
+    getCalled = 0;
+    assertEquals(42, this[x]);
+    assertEquals(1, getCalled);
+    assertEquals(0, setCalled);
+
+    getCalled = 0;
+    setCalled = 0;
+    this[x] = 43;
+    assertEquals(0, getCalled);
+    assertEquals(1, setCalled);
+
+    getCalled = 0;
+    setCalled = 0;
+    super[x] = 15;
+    assertEquals(0, setCalled);
+    assertEquals(0, getCalled);
+
+    assertEquals(15, this[x]);
+    assertEquals(0, getCalled);
+    assertEquals(0, setCalled);
+
+  }.toMethod(Derived.prototype);
+
+  new Derived().mSloppy();
+  new Derived().mStrict();
+}());
+
+
+(function TestKeyedNumericSetterNoProtoWalk() {
+  var x = 42;
+  function Base() {}
+  function Derived() {}
+  var getCalled;
+  var setCalled;
+  Derived.prototype = {
+    __proto__ : Base.prototype,
+  };
+
+  Object.defineProperty(Derived.prototype, x, {
+    get: function() { getCalled++; return 42; },
+    set: function(v) { setCalled++; }
+  });
+
+  Derived.prototype.mSloppy = function() {
+    setCalled = 0;
+    getCalled = 0;
+    assertEquals(42, this[x]);
+    assertEquals(1, getCalled);
+    assertEquals(0, setCalled);
+
+    getCalled = 0;
+    setCalled = 0;
+    this[x] = 43;
+    assertEquals(0, getCalled);
+    assertEquals(1, setCalled);
+
+    getCalled = 0;
+    setCalled = 0;
+    super[x] = 15;
+    assertEquals(0, setCalled);
+    assertEquals(0, getCalled);
+
+    assertEquals(15, this[x]);
+    assertEquals(0, getCalled);
+    assertEquals(0, setCalled);
+
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.mStrict = function() {
+    'use strict';
+    setCalled = 0;
+    getCalled = 0;
+    assertEquals(42, this[x]);
+    assertEquals(1, getCalled);
+    assertEquals(0, setCalled);
+
+    getCalled = 0;
+    setCalled = 0;
+    this[x] = 43;
+    assertEquals(0, getCalled);
+    assertEquals(1, setCalled);
+
+    getCalled = 0;
+    setCalled = 0;
+    super[x] = 15;
+    assertEquals(0, setCalled);
+    assertEquals(0, getCalled);
+
+    assertEquals(15, this[x]);
+    assertEquals(0, getCalled);
+    assertEquals(0, setCalled);
+
+  }.toMethod(Derived.prototype);
+
+  new Derived().mSloppy();
+  new Derived().mStrict();
+}());
+
+
+(function TestSetterDoesNotReconfigure() {
+  function Base() {}
+  function Derived() {}
+
+  Derived.prototype.mStrict = function (){
+    'use strict';
+    super.nonEnumConfig = 5;
+    var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumConfig');
+    assertEquals(5, d1.value);
+    assertTrue(d1.configurable);
+    assertFalse(d1.enumerable);
+
+    super.nonEnumNonConfig = 5;
+    var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumNonConfig');
+    assertEquals(5, d1.value);
+    assertFalse(d1.configurable);
+    assertFalse(d1.enumerable);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.mSloppy = function (){
+    super.nonEnumConfig = 42;
+    var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumConfig');
+    assertEquals(42, d1.value);
+    assertTrue(d1.configurable);
+    assertFalse(d1.enumerable);
+
+    super.nonEnumNonConfig = 42;
+    var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumNonConfig');
+    assertEquals(42, d1.value);
+    assertFalse(d1.configurable);
+    assertFalse(d1.enumerable);
+  }.toMethod(Derived.prototype);
+
+  var d = new Derived();
+  Object.defineProperty(d, 'nonEnumConfig',
+      { value : 0, enumerable : false, configurable : true, writable : true });
+  Object.defineProperty(d, 'nonEnumNonConfig',
+      { value : 0, enumerable : false, configurable : false, writable : true });
+  d.mStrict();
+  d.mSloppy();
+}());
+
+
+(function TestKeyedSetterDoesNotReconfigure() {
+  var nonEnumConfig = 'nonEnumConfig';
+  var nonEnumNonConfig = 'nonEnumNonConfig';
+  function Base() {}
+  function Derived() {}
+
+  Derived.prototype = { __proto__: Base.prototype };
+
+  Derived.prototype.mStrict = function (){
+    'use strict';
+    super[nonEnumConfig] = 5;
+    var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig);
+    assertEquals(5, d1.value);
+    assertTrue(d1.configurable);
+    assertFalse(d1.enumerable);
+
+    super[nonEnumNonConfig] = 5;
+    var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig);
+    assertEquals(5, d1.value);
+    assertFalse(d1.configurable);
+    assertFalse(d1.enumerable);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.mSloppy = function (){
+    super[nonEnumConfig] = 42;
+    var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig);
+    assertEquals(42, d1.value);
+    assertTrue(d1.configurable);
+    assertFalse(d1.enumerable);
+
+    super[nonEnumNonConfig] = 42;
+    var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig);
+    assertEquals(42, d1.value);
+    assertFalse(d1.configurable);
+    assertFalse(d1.enumerable);
+  }.toMethod(Derived.prototype);
+
+  var d = new Derived();
+  Object.defineProperty(d, nonEnumConfig,
+      { value : 0, enumerable : false, configurable : true, writable : true });
+  Object.defineProperty(d, nonEnumNonConfig,
+      { value : 0, enumerable : false, configurable : false, writable : true });
+  d.mStrict();
+  d.mSloppy();
+}());
+
+
+(function TestKeyedNumericSetterDoesNotReconfigure() {
+  var nonEnumConfig = 42;
+  var nonEnumNonConfig = 43;
+  function Base() {}
+  function Derived() {}
+
+  Derived.prototype = { __proto__: Base.prototype };
+
+  Derived.prototype.mStrict = function (){
+    'use strict';
+    super[nonEnumConfig] = 5;
+    var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig);
+    assertEquals(5, d1.value);
+    assertTrue(d1.configurable);
+    assertFalse(d1.enumerable);
+
+    super[nonEnumNonConfig] = 5;
+    var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig);
+    assertEquals(5, d1.value);
+    assertFalse(d1.configurable);
+    assertFalse(d1.enumerable);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.mSloppy = function (){
+    super[nonEnumConfig] = 42;
+    var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig);
+    assertEquals(42, d1.value);
+    assertTrue(d1.configurable);
+    assertFalse(d1.enumerable);
+
+    super[nonEnumNonConfig] = 42;
+    var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig);
+    assertEquals(42, d1.value);
+    assertFalse(d1.configurable);
+    assertFalse(d1.enumerable);
+  }.toMethod(Derived.prototype);
+
+  var d = new Derived();
+  Object.defineProperty(d, nonEnumConfig,
+      { value : 0, enumerable : false, configurable : true, writable : true });
+  Object.defineProperty(d, nonEnumNonConfig,
+      { value : 0, enumerable : false, configurable : false, writable : true });
+  d.mStrict();
+  d.mSloppy();
+}());
+
+
+(function TestCountOperations() {
+  function Base() {}
+  Base.prototype = {
+    constructor: Base,
+    get x() {
+      return this._x;
+    },
+    set x(v) {
+      this._x = v;
+    },
+    _x: 1
+  };
+
+  function Derived() {}
+  Derived.__proto__ = Base;
+  Derived.prototype = {
+    __proto__: Base.prototype,
+    constructor: Derived,
+    _x: 2
+  };
+
+  Derived.prototype.testCounts = function() {
+    assertEquals(2, this._x);
+    assertEquals(2, super.x);
+    super.x++;
+    assertEquals(3, super.x);
+    ++super.x;
+    assertEquals(4, super.x);
+    assertEquals(4, super.x++);
+    assertEquals(5, super.x);
+    assertEquals(6, ++super.x);
+    assertEquals(6, super.x);
+    assertEquals(6, this._x);
+
+    super.x--;
+    assertEquals(5, super.x);
+    --super.x;
+    assertEquals(4, super.x);
+    assertEquals(4, super.x--);
+    assertEquals(3, super.x);
+    assertEquals(2, --super.x);
+    assertEquals(2, super.x);
+    assertEquals(2, this._x);
+  }.toMethod(Derived.prototype);
+  new Derived().testCounts();
+}());
+
+
+(function TestKeyedCountOperations() {
+  var x = 'x';
+  function Base() {}
+  Base.prototype = {
+    constructor: Base,
+    get x() {
+      return this._x;
+    },
+    set x(v) {
+      this._x = v;
+    },
+    _x: 1
+  };
+
+  function Derived() {}
+  Derived.__proto__ = Base;
+  Derived.prototype = {
+    __proto__: Base.prototype,
+    constructor: Derived,
+    _x: 2
+  };
+
+  Derived.prototype.testCounts = function() {
+    assertEquals(2, this._x);
+    assertEquals(2, super[x]);
+    super[x]++;
+    assertEquals(3, super[x]);
+    ++super[x];
+    assertEquals(4, super[x]);
+    assertEquals(4, super[x]++);
+    assertEquals(5, super[x]);
+    assertEquals(6, ++super[x]);
+    assertEquals(6, super[x]);
+    assertEquals(6, this._x);
+
+    super[x]--;
+    assertEquals(5, super[x]);
+    --super[x];
+    assertEquals(4, super[x]);
+    assertEquals(4, super[x]--);
+    assertEquals(3, super[x]);
+    assertEquals(2, --super[x]);
+    assertEquals(2, super[x]);
+    assertEquals(2, this._x);
+  }.toMethod(Derived.prototype);
+  new Derived().testCounts();
+}());
+
+
+(function TestKeyedNumericCountOperations() {
+  var x = 42;
+  function Base() {}
+  Base.prototype = {
+    constructor: Base,
+    _x: 1
+  };
+
+  Object.defineProperty(Base.prototype, x, {
+    get: function() { return this._x; },
+    set: function(v) { this._x = v;; }
+  });
+
+  function Derived() {}
+  Derived.__proto__ = Base;
+  Derived.prototype = {
+    __proto__: Base.prototype,
+    constructor: Derived,
+    _x: 2
+  };
+
+  Derived.prototype.testCounts = function() {
+    assertEquals(2, this._x);
+    assertEquals(2, super[x]);
+    super[x]++;
+    assertEquals(3, super[x]);
+    ++super[x];
+    assertEquals(4, super[x]);
+    assertEquals(4, super[x]++);
+    assertEquals(5, super[x]);
+    assertEquals(6, ++super[x]);
+    assertEquals(6, super[x]);
+    assertEquals(6, this._x);
+
+    super[x]--;
+    assertEquals(5, super[x]);
+    --super[x];
+    assertEquals(4, super[x]);
+    assertEquals(4, super[x]--);
+    assertEquals(3, super[x]);
+    assertEquals(2, --super[x]);
+    assertEquals(2, super[x]);
+    assertEquals(2, this._x);
+  }.toMethod(Derived.prototype);
+  new Derived().testCounts();
+}());
+
+
+(function TestSetterSuperNonWritable() {
+  function Base() {}
+  Object.defineProperty(Base.prototype, 'x', { value : 27, writable: false });
+  function Derived() {}
+
+  Derived.prototype = { __proto__: Base.prototype, constructor: Derived };
+
+  Derived.prototype.mSloppy = function() {
+    assertEquals(27, super.x);
+    assertEquals(27, this.x);
+    super.x = 10;
+    assertEquals(27, super.x);
+    assertEquals(27, this.x);
+  }.toMethod(Derived.prototype);
+  Derived.prototype.mStrict = function() {
+    'use strict';
+    assertEquals(27, super.x);
+    assertEquals(27, this.x);
+    var ex = null;
+    try { super.x = 10; } catch(e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+    assertEquals(27, super.x);
+    assertEquals(27, this.x);
+  }.toMethod(Derived.prototype);
+  new Derived().mSloppy();
+  new Derived().mStrict();
+}());
+
+
+(function TestSetterKeyedSuperNonWritable() {
+  var x = 'xyz';
+  function Base() {}
+  Object.defineProperty(Base.prototype, x, { value : 27, writable: false });
+  function Derived() {}
+
+  Derived.prototype = { __proto__: Base.prototype, constructor: Derived };
+
+  Derived.prototype.mSloppy = function() {
+    assertEquals(27, super[x]);
+    assertEquals(27, this[x]);
+    super[x] = 10;
+    assertEquals(27, super[x]);
+    assertEquals(27, this[x]);
+  }.toMethod(Derived.prototype);
+  Derived.prototype.mStrict = function() {
+    'use strict';
+    assertEquals(27, super[x]);
+    assertEquals(27, this[x]);
+    var ex = null;
+    try { super[x] = 10; } catch(e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+    assertEquals(27, super[x]);
+    assertEquals(27, this[x]);
+  }.toMethod(Derived.prototype);
+  new Derived().mSloppy();
+  new Derived().mStrict();
+}());
+
+
+(function TestSetterKeyedNumericSuperNonWritable() {
+  var x = 42;
+  function Base() {}
+  Object.defineProperty(Base.prototype, x, { value : 27, writable: false });
+  function Derived() {}
+
+  Derived.prototype = { __proto__: Base.prototype, constructor: Derived };
+
+  Derived.prototype.mSloppy = function() {
+    assertEquals(27, super[x]);
+    assertEquals(27, this[x]);
+    super[x] = 10;
+    assertEquals(27, super[x]);
+    assertEquals(27, this[x]);
+  }.toMethod(Derived.prototype);
+  Derived.prototype.mStrict = function() {
+    'use strict';
+    assertEquals(27, super[x]);
+    assertEquals(27, this[x]);
+    var ex = null;
+    try { super[x] = 10; } catch(e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+    assertEquals(27, super[x]);
+    assertEquals(27, this[x]);
+  }.toMethod(Derived.prototype);
+  new Derived().mSloppy();
+  new Derived().mStrict();
+}());
+
+
+function Subclass(base, constructor) {
+  var homeObject = {
+    __proto__: base.prototype,
+    constructor: constructor
+  };
+  constructor.__proto__ = base;
+  constructor.prototype = homeObject;
+  // not doing toMethod: home object is not required for
+  // super constructor calls.
+  return constructor;
+}
+
+(function TestSuperCall() {
+  var baseCalled = 0;
+  var derivedCalled = 0;
+  var derivedDerivedCalled = 0;
+
+  function Base() {
+    baseCalled++;
+  }
+
+  var Derived = Subclass(Base, function () {
+    super();
+    derivedCalled++;
+  });
+
+  assertEquals(Base, Base.prototype.constructor);
+  assertEquals(Base.prototype, Derived.prototype.__proto__);
+
+  baseCalled = 0;
+  derivedCalled = 0;
+  new Derived();
+  assertEquals(1, baseCalled);
+  assertEquals(1, derivedCalled);
+
+  var DerivedDerived = Subclass(Derived, function () {
+    super();
+    derivedDerivedCalled++;
+  });
+
+  baseCalled = 0;
+  derivedCalled = 0;
+  derivedDerivedCalled = 0;
+  new DerivedDerived();
+  assertEquals(1, baseCalled);
+  assertEquals(1, derivedCalled);
+  assertEquals(1, derivedDerivedCalled);
+
+  function Base2(v) {
+    this.fromBase = v;
+  }
+  var Derived2 = Subclass(Base2, function (v1, v2) {
+    super(v1);
+    this.fromDerived = v2;
+  });
+
+  var d = new Derived2("base", "derived");
+  assertEquals("base", d.fromBase);
+  assertEquals("derived", d.fromDerived);
+
+  function ImplicitSubclassOfFunction() {
+    super();
+    this.x = 123;
+  }
+
+  var o = new ImplicitSubclassOfFunction();
+  assertEquals(123, o.x);
+
+  var calls = 0;
+  function G() {
+    calls++;
+  }
+  function F() {
+    super();
+  }
+  F.__proto__ = G;
+  new F();
+  assertEquals(1, calls);
+  F.__proto__ = function() {};
+  new F();
+  assertEquals(1, calls);
+}());
+
+
+(function TestNewSuper() {
+  var baseCalled = 0;
+  var derivedCalled = 0;
+
+  function Base() {
+    baseCalled++;
+    this.x = 15;
+  }
+
+
+  var Derived = Subclass(Base, function() {
+    baseCalled = 0;
+    var b = new super();
+    assertEquals(1, baseCalled)
+    assertEquals(Base.prototype, b.__proto__);
+    assertEquals(15, b.x);
+    assertEquals(undefined, this.x);
+    derivedCalled++;
+  });
+
+  derivedCalled = 0;
+  new Derived();
+  assertEquals(1, derivedCalled);
+}());
+
+
+(function TestSuperCallErrorCases() {
+  function T() {
+    super();
+  }
+  T.__proto__ = null;
+  // Spec says ReferenceError here, but for other IsCallable failures
+  // we throw TypeError.
+  // Filed https://bugs.ecmascript.org/show_bug.cgi?id=3282
+  assertThrows(function() { new T(); }, TypeError);
+
+  function T1() {
+    var b = new super();
+  }
+  T1.__proto = null;
+  assertThrows(function() { new T1(); }, TypeError);
 }());
-*/