| // Copyright 2014 the V8 project authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | // Flags: --allow-natives-syntax | 
 |  | 
 | (function TestSuperNamedLoads() { | 
 |   function Base() { } | 
 |   function fBase() { } | 
 |   Base.prototype = { | 
 |     f() { | 
 |       return "Base " + this.toString(); | 
 |     }, | 
 |     x: 15, | 
 |     toString() { | 
 |       return "this is Base"; | 
 |     } | 
 |   }; | 
 |  | 
 |   function Derived() { | 
 |     this.derivedDataProperty = "xxx"; | 
 |   } | 
 |   Derived.prototype = { | 
 |     __proto__: Base.prototype, | 
 |     toString() { return "this is Derived"; }, | 
 |     x: 27, | 
 |     f() { | 
 |       assertEquals("Base this is Derived", super.f()); | 
 |       var a = super.x; | 
 |       assertEquals(15, a); | 
 |       assertEquals(15, super.x); | 
 |       assertEquals(27, this.x); | 
 |       return "Derived"; | 
 |     } | 
 |   }; | 
 |  | 
 |   assertEquals("Base this is Base", new Base().f()); | 
 |   assertEquals("Derived", new Derived().f()); | 
 | }()); | 
 |  | 
 |  | 
 | (function TestSuperKeyedLoads() { | 
 |   'use strict'; | 
 |  | 
 |   var x = 'x'; | 
 |   var derivedDataProperty = 'derivedDataProperty'; | 
 |   var f = 'f'; | 
 |  | 
 |   class Base { | 
 |     f() { | 
 |       return "Base " + this.toString(); | 
 |     } | 
 |     toString() { | 
 |       return "this is Base"; | 
 |     } | 
 |   } | 
 |  | 
 |   Base.prototype[x] = 15; | 
 |  | 
 |   function Derived() { | 
 |     this[derivedDataProperty] = "xxx"; | 
 |   } | 
 |   Derived.prototype = { | 
 |     __proto__: Base.prototype, | 
 |     toString() { return "this is Derived"; }, | 
 |     x: 27, | 
 |     f() { | 
 |       assertEquals("Base this is Derived", super[f]()); | 
 |       var a = super[x]; | 
 |       assertEquals(15, a); | 
 |       assertEquals(15, super[x]); | 
 |       assertEquals(27, this[x]); | 
 |       return "Derived"; | 
 |     } | 
 |   }; | 
 |  | 
 |   assertEquals("Base this is Base", new Base().f()); | 
 |   assertEquals("Derived", new Derived().f()); | 
 | }()); | 
 |  | 
 |  | 
 | (function TestSuperKeywordNonMethod() { | 
 |   'use strict'; | 
 |  | 
 |   class C { | 
 |     f() { | 
 |       super.unknown(); | 
 |     } | 
 |   } | 
 |  | 
 |   assertThrows(function() { | 
 |     new C().f(); | 
 |   }, TypeError); | 
 | }()); | 
 |  | 
 |  | 
 | (function TestGetter() { | 
 |   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', | 
 |     testGetter() { | 
 |       return super.x; | 
 |     }, | 
 |     testGetterStrict() { | 
 |       'use strict'; | 
 |       return super.x; | 
 |     } | 
 |   }; | 
 |  | 
 |   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', | 
 |     testGetter() { | 
 |       return super[x]; | 
 |     }, | 
 |     testGetterStrict() { | 
 |       'use strict'; | 
 |       return super[x]; | 
 |     }, | 
 |     testGetterWithToString() { | 
 |       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]); | 
 |     } | 
 |   }; | 
 |  | 
 |   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', | 
 |     testGetter() { | 
 |       return super[x]; | 
 |     }, | 
 |     testGetterStrict() { | 
 |       'use strict'; | 
 |       return super[x]; | 
 |     }, | 
 |     testGetterWithToString() { | 
 |       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]); | 
 |     } | 
 |   }; | 
 |  | 
 |   derived = new Derived(); | 
 |   assertEquals('derived', derived.testGetter()); | 
 |   derived = new Derived(); | 
 |   assertEquals('derived', derived.testGetterStrict()); | 
 |   derived = new Derived(); | 
 |   derived.testGetterWithToString(); | 
 | }()); | 
 |  | 
 |  | 
 | (function TestSetter() { | 
 |   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', | 
 |     testSetter() { | 
 |       assertEquals('foobar', super.x = 'foobar'); | 
 |       assertEquals('foobarabc', super.x += 'abc'); | 
 |     }, | 
 |     testSetterStrict() { | 
 |       'use strict'; | 
 |       assertEquals('foobar', super.x = 'foobar'); | 
 |       assertEquals('foobarabc', super.x += 'abc'); | 
 |     } | 
 |   }; | 
 |  | 
 |   var d = new Derived(); | 
 |   d.testSetter(); | 
 |   assertEquals('base', Base.prototype._x); | 
 |   assertEquals('foobarabc', d._x); | 
 |   d._x = ''; | 
 |  | 
 |   d.testSetterStrict(); | 
 |   assertEquals('base', Base.prototype._x); | 
 |   assertEquals('foobarabc', d._x); | 
 | }()); | 
 |  | 
 |  | 
 | (function TestSetterNumericKeyed() { | 
 |   var x = 42; | 
 |   function Base() {} | 
 |   Base.prototype = { | 
 |     constructor: Base, | 
 |     _x: 'base' | 
 |   }; | 
 |  | 
 |   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: 'derived', | 
 |     testSetter() { | 
 |       assertEquals('foobar', super[x] = 'foobar'); | 
 |       assertEquals('foobarabc', super[x] += 'abc'); | 
 |     }, | 
 |     testSetterStrict() { | 
 |       'use strict'; | 
 |       assertEquals('foobar', super[x] = 'foobar'); | 
 |       assertEquals('foobarabc', super[x] += 'abc'); | 
 |     }, | 
 |     testSetterWithToString() { | 
 |       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 d = new Derived(); | 
 |   d.testSetter(); | 
 |   assertEquals('base', Base.prototype._x); | 
 |   assertEquals('foobarabc', d._x); | 
 |   d._x = ''; | 
 |  | 
 |   d.testSetterStrict(); | 
 |   assertEquals('base', Base.prototype._x); | 
 |   assertEquals('foobarabc', d._x); | 
 |  | 
 |   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', | 
 |     testSetter() { | 
 |       assertEquals('foobar', super[x] = 'foobar'); | 
 |       assertEquals('foobarabc', super[x] += 'abc'); | 
 |     }, | 
 |     testSetterStrict() { | 
 |       'use strict'; | 
 |       assertEquals('foobar', super[x] = 'foobar'); | 
 |       assertEquals('foobarabc', super[x] += 'abc'); | 
 |     }, | 
 |     testSetterWithToString() { | 
 |       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); | 
 |     } | 
 |   }; | 
 |  | 
 |   var d = new Derived(); | 
 |   d.testSetter(); | 
 |   assertEquals('base', Base.prototype._x); | 
 |   assertEquals('foobarabc', d._x); | 
 |   d._x = ''; | 
 |   d.testSetterStrict(); | 
 |   assertEquals('base', Base.prototype._x); | 
 |   assertEquals('foobarabc', d._x); | 
 |  | 
 |   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, | 
 |     testSetter() { | 
 |       assertEquals('x from Base', super.x); | 
 |       super.x = 'data property'; | 
 |       assertEquals('x from Base', super.x); | 
 |       assertEquals('data property', this.x); | 
 |     } | 
 |   }; | 
 |  | 
 |   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, | 
 |     testSetter() { | 
 |       assertEquals('x from Base', super[x]); | 
 |       super[x] = 'data property'; | 
 |       assertEquals('x from Base', super[x]); | 
 |       assertEquals('data property', this[x]); | 
 |     } | 
 |   }; | 
 |  | 
 |   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, | 
 |     testSetter() { | 
 |       assertEquals('x from Base', super[x]); | 
 |       super[x] = 'data property'; | 
 |       assertEquals('x from Base', super[x]); | 
 |       assertEquals('data property', this[x]); | 
 |     } | 
 |   }; | 
 |  | 
 |   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, | 
 |     testSetter() { | 
 |       setCalled = 0; | 
 |       getCalled = 0; | 
 |       assertEquals('object', typeof this); | 
 |       assertInstanceof(this, 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); | 
 |     }, | 
 |     testSetterStrict() { | 
 |       '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; } | 
 |       assertInstanceof(ex, TypeError); | 
 |     } | 
 |   } | 
 |  | 
 |   Derived.prototype.testSetter.call(42); | 
 |   Derived.prototype.testSetterStrict.call(42); | 
 |  | 
 |   function DerivedFromString() {} | 
 |   DerivedFromString.prototype = { | 
 |     __proto__: String.prototype, | 
 |     f() { | 
 |       'use strict'; | 
 |       assertTrue(42 === this); | 
 |       assertEquals(String.prototype.toString, super.toString); | 
 |       var ex; | 
 |       try { | 
 |         super.toString(); | 
 |       } catch(e) { ex = e; } | 
 |  | 
 |       assertInstanceof(ex, TypeError); | 
 |     } | 
 |   }; | 
 |  | 
 |   DerivedFromString.prototype.f.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, | 
 |     testSetter() { | 
 |       setCalled = 0; | 
 |       getCalled = 0; | 
 |       assertEquals('object', typeof this); | 
 |       assertInstanceof(this, 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]); | 
 |     }, | 
 |     testSetterStrict() { | 
 |       '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; } | 
 |       assertInstanceof(ex,TypeError); | 
 |     } | 
 |   }; | 
 |  | 
 |   Derived.prototype.testSetter.call(42); | 
 |   Derived.prototype.testSetterStrict.call(42); | 
 |  | 
 |   function DerivedFromString() {} | 
 |   DerivedFromString.prototype = { | 
 |     __proto__: String.prototype, | 
 |     f() { | 
 |       'use strict'; | 
 |       assertTrue(42 === this); | 
 |       assertEquals(String.prototype.toString, super[toString]); | 
 |       var ex; | 
 |       try { | 
 |         super[toString](); | 
 |       } catch(e) { ex = e; } | 
 |  | 
 |       assertInstanceof(ex, TypeError); | 
 |     } | 
 |   }; | 
 |   DerivedFromString.prototype.f.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, | 
 |     testSetter() { | 
 |       setCalled = 0; | 
 |       getCalled = 0; | 
 |       assertEquals('object', typeof this); | 
 |       assertInstanceof(this, 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]); | 
 |     }, | 
 |     testSetterStrict() { | 
 |       '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; } | 
 |       assertInstanceof(ex, TypeError); | 
 |     } | 
 |   }; | 
 |  | 
 |   Derived.prototype.testSetter.call(42); | 
 |   Derived.prototype.testSetterStrict.call(42); | 
 | }()); | 
 |  | 
 |  | 
 | (function TestKeyedNumericSetterOnExotics() { | 
 |   function Base() {} | 
 |   function Derived() {} | 
 |   Derived.prototype = { | 
 |     __proto__: Base.prototype, | 
 |     callSetterOnArray() { | 
 |       super[42] = 1; | 
 |     }, | 
 |     callStrictSetterOnString() { | 
 |       'use strict'; | 
 |       assertEquals('string', typeof this); | 
 |       assertTrue('abcdef' === this); | 
 |       var ex = null; | 
 |       try { | 
 |         super[5] = 'q'; | 
 |       } catch(e) { ex = e; } | 
 |       assertInstanceof(ex, TypeError); | 
 |  | 
 |       ex = null; | 
 |       try { | 
 |         super[1024] = 'q'; | 
 |       } catch(e) { ex = e; } | 
 |       assertInstanceof(ex, TypeError); | 
 |     } | 
 |   }; | 
 |  | 
 |   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, | 
 |     mSloppy() { | 
 |       assertEquals(undefined, super.x); | 
 |       assertEquals(undefined, this.x); | 
 |       super.x = 10; | 
 |       assertEquals(10, this.x); | 
 |       assertEquals(undefined, super.x); | 
 |     }, | 
 |     mStrict() { | 
 |       'use strict'; | 
 |       assertEquals(undefined, super.x); | 
 |       assertEquals(undefined, this.x); | 
 |       super.x = 10; | 
 |       assertEquals(10, this.x); | 
 |       assertEquals(undefined, super.x); | 
 |     } | 
 |   }; | 
 |  | 
 |   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, | 
 |     mSloppy() { | 
 |       assertEquals(undefined, super[x]); | 
 |       assertEquals(undefined, this[x]); | 
 |       super[x] = 10; | 
 |       assertEquals(10, this[x]); | 
 |       assertEquals(undefined, super[x]); | 
 |     }, | 
 |     mStrict() { | 
 |       'use strict'; | 
 |       assertEquals(undefined, super[x]); | 
 |       assertEquals(undefined, this[x]); | 
 |       super[x] = 10; | 
 |       assertEquals(10, this[x]); | 
 |       assertEquals(undefined, super[x]); | 
 |     } | 
 |   }; | 
 |   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, | 
 |     mSloppy() { | 
 |       assertEquals(undefined, super[x]); | 
 |       assertEquals(undefined, this[x]); | 
 |       super[x] = 10; | 
 |       assertEquals(10, this[x]); | 
 |       assertEquals(undefined, super[x]); | 
 |     }, | 
 |     mStrict() { | 
 |       'use strict'; | 
 |       assertEquals(undefined, super[x]); | 
 |       assertEquals(undefined, this[x]); | 
 |       super[x] = 10; | 
 |       assertEquals(10, this[x]); | 
 |       assertEquals(undefined, super[x]); | 
 |     } | 
 |   }; | 
 |   var d = new Derived(); | 
 |   d.mSloppy(); | 
 |   assertEquals(10, d[x]); | 
 |   var d1 = new Derived(); | 
 |   d1.mStrict(); | 
 |   assertEquals(10, d[x]); | 
 | }()); | 
 |  | 
 |  | 
 | (function TestSetterCreatingOwnPropertiesReconfigurable() { | 
 |   function Base() {} | 
 |   function Derived() {} | 
 |   Derived.prototype = { | 
 |     __proto__: Base.prototype, | 
 |     mSloppy() { | 
 |       assertEquals(42, this.ownReadOnly); | 
 |       super.ownReadOnly = 55; | 
 |       assertSame(undefined, super.ownReadOnly); | 
 |       assertEquals(42, this.ownReadOnly); | 
 |       assertFalse(Base.prototype.hasOwnProperty('ownReadOnly')); | 
 |  | 
 |       assertEquals(15, this.ownReadonlyAccessor); | 
 |       super.ownReadonlyAccessor = 25; | 
 |       assertSame(undefined, super.ownReadonlyAccessor); | 
 |       assertEquals(15, this.ownReadonlyAccessor); | 
 |       assertFalse(Base.prototype.hasOwnProperty('ownReadonlyAccessor')); | 
 |  | 
 |       super.ownSetter = 35; | 
 |       assertSame(undefined, super.ownSetter); | 
 |       var descr = Object.getOwnPropertyDescriptor(this, 'ownSetter'); | 
 |       assertTrue('set' in descr); | 
 |       assertFalse(Base.prototype.hasOwnProperty('ownSetter')); | 
 |     }, | 
 |     mStrict() { | 
 |       'use strict'; | 
 |       assertEquals(42, this.ownReadOnly); | 
 |       assertThrows(() => {super.ownReadOnly = 55}, TypeError); | 
 |       assertSame(undefined, super.ownReadOnly); | 
 |       assertEquals(42, this.ownReadOnly); | 
 |       assertFalse(Base.prototype.hasOwnProperty('ownReadOnly')); | 
 |  | 
 |       assertEquals(15, this.ownReadonlyAccessor); | 
 |       assertThrows(() => {super.ownReadonlyAccessor = 25}, TypeError); | 
 |       assertSame(undefined, super.ownReadonlyAccessor); | 
 |       assertEquals(15, this.ownReadonlyAccessor); | 
 |       assertFalse(Base.prototype.hasOwnProperty('ownReadonlyAccessor')); | 
 |  | 
 |       assertThrows(() => {super.ownSetter = 35}, TypeError); | 
 |       assertSame(undefined, super.ownSetter); | 
 |       var descr = Object.getOwnPropertyDescriptor(this, 'ownSetter'); | 
 |       assertTrue('set' in descr); | 
 |       assertFalse(Base.prototype.hasOwnProperty('ownSetter')); | 
 |     }, | 
 |   }; | 
 |  | 
 |   var d = new Derived(); | 
 |   Object.defineProperty(d, 'ownReadOnly', { | 
 |     value: 42, | 
 |     writable: false, | 
 |     configurable: true | 
 |   }); | 
 |   Object.defineProperty(d, 'ownSetter', { | 
 |     set: function() { assertUnreachable(); }, | 
 |     configurable: true | 
 |   }); | 
 |   Object.defineProperty(d, 'ownReadonlyAccessor', { | 
 |     get: function() { return 15; }, | 
 |     configurable: true | 
 |   }); | 
 |  | 
 |   d.mSloppy(); | 
 |  | 
 |   var d = new Derived(); | 
 |   Object.defineProperty(d, 'ownReadOnly', { | 
 |     value: 42, | 
 |     writable: false, | 
 |     configurable: true | 
 |   }); | 
 |   Object.defineProperty(d, 'ownSetter', { | 
 |     set: function() { assertUnreachable(); }, | 
 |     configurable: true | 
 |   }); | 
 |   Object.defineProperty(d, 'ownReadonlyAccessor', { | 
 |     get: function() { return 15; }, | 
 |     configurable: true | 
 |   }); | 
 |   d.mStrict(); | 
 | }()); | 
 |  | 
 |  | 
 | (function TestSetterCreatingOwnPropertiesNonConfigurable() { | 
 |   function Base() {} | 
 |   function Derived() {} | 
 |   Derived.prototype = { | 
 |     __proto__: Base.prototype, | 
 |     mSloppy() { | 
 |       assertEquals(42, this.ownReadOnly); | 
 |       super.ownReadOnly = 55; | 
 |       assertEquals(42, this.ownReadOnly); | 
 |       var descr = Object.getOwnPropertyDescriptor(this, 'ownReadOnly'); | 
 |       assertEquals(42, descr.value); | 
 |       assertFalse(descr.configurable); | 
 |       assertFalse(descr.enumerable); | 
 |       assertFalse(descr.writable); | 
 |       assertFalse(Base.prototype.hasOwnProperty('ownReadOnly')); | 
 |  | 
 |       assertEquals(15, this.ownReadonlyAccessor); | 
 |       super.ownReadonlyAccessor = 25; | 
 |       assertSame(undefined, super.ownReadonlyAccessor); | 
 |       assertEquals(15, this.ownReadonlyAccessor); | 
 |       var descr = Object.getOwnPropertyDescriptor(this, 'ownReadonlyAccessor'); | 
 |       assertFalse(descr.configurable); | 
 |       assertFalse(descr.enumerable); | 
 |       assertFalse(Base.prototype.hasOwnProperty('ownReadonlyAccessor')); | 
 |  | 
 |       super.ownSetter = 35; | 
 |       var descr = Object.getOwnPropertyDescriptor(this, 'ownSetter'); | 
 |       assertFalse(descr.configurable); | 
 |       assertFalse(descr.enumerable); | 
 |       assertFalse(Base.prototype.hasOwnProperty('ownSetter')); | 
 |     }, | 
 |     mStrict() { | 
 |       'use strict'; | 
 |       var ex; | 
 |       assertEquals(42, this.ownReadOnly); | 
 |       try { | 
 |         super.ownReadOnly = 55; | 
 |       } catch (e) { | 
 |         ex = e; | 
 |       } | 
 |       assertInstanceof(ex, TypeError); | 
 |       assertEquals( | 
 |           "Cannot assign to read only property 'ownReadOnly' of object '#<Base>'", | 
 |           ex.message); | 
 |       assertEquals(42, this.ownReadOnly); | 
 |  | 
 |       ex = null; | 
 |       assertEquals(15, this.ownReadonlyAccessor); | 
 |       try { | 
 |         super.ownReadonlyAccessor = 25; | 
 |       } catch (e) { | 
 |         ex = e; | 
 |       } | 
 |       assertInstanceof(ex, TypeError); | 
 |       assertEquals('Cannot redefine property: ownReadonlyAccessor', ex.message); | 
 |       assertEquals(15, this.ownReadonlyAccessor); | 
 |  | 
 |       ex = null; | 
 |       try { | 
 |         super.ownSetter = 35; | 
 |       } catch (e) { | 
 |         ex = e; | 
 |       } | 
 |       assertInstanceof(ex, TypeError); | 
 |       assertEquals('Cannot redefine property: ownSetter', ex.message); | 
 |     } | 
 |   }; | 
 |  | 
 |   var d = new Derived(); | 
 |   Object.defineProperty(d, 'ownReadOnly', { value : 42, writable : false }); | 
 |   Object.defineProperty(d, 'ownSetter', | 
 |       { set : function() { assertUnreachable(); } }); | 
 |   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, | 
 |     testIter() { | 
 |       setCalled = 0; | 
 |       getCalled = 0; | 
 |       for (super.x in [1,2,3]) {} | 
 |       assertEquals(0, getCalled); | 
 |       assertEquals(3, setCalled); | 
 |       assertEquals(["0", "1", "2"], this.x_); | 
 |     }, | 
 |     testIterKeyed() { | 
 |       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_); | 
 |     } | 
 |   }; | 
 |  | 
 |   new Derived().testIter(); | 
 |  | 
 |   var x = 'x'; | 
 |  | 
 |   new Derived().testIterKeyed(); | 
 | }()); | 
 |  | 
 |  | 
 | function TestKeyedSetterCreatingOwnPropertiesReconfigurable(ownReadOnly, | 
 |     ownReadonlyAccessor, ownSetter) { | 
 |   function Base() {} | 
 |   function Derived() {} | 
 |   Derived.prototype = { | 
 |     __proto__: Base.prototype, | 
 |     mSloppy() { | 
 |       assertEquals(42, this[ownReadOnly]); | 
 |       super[ownReadOnly] = 55; | 
 |       assertSame(undefined, super[ownReadOnly]); | 
 |       assertEquals(42, this[ownReadOnly]); | 
 |       assertFalse(Base.prototype.hasOwnProperty(ownReadOnly)); | 
 |  | 
 |       assertEquals(15, this[ownReadonlyAccessor]); | 
 |       super[ownReadonlyAccessor] = 25; | 
 |       assertSame(undefined, super[ownReadonlyAccessor]); | 
 |       assertEquals(15, this[ownReadonlyAccessor]); | 
 |       assertFalse(Base.prototype.hasOwnProperty(ownReadonlyAccessor)); | 
 |  | 
 |       super[ownSetter] = 35; | 
 |       assertSame(undefined, super[ownSetter]); | 
 |       var descr = Object.getOwnPropertyDescriptor(this, ownSetter); | 
 |       assertTrue('set' in descr); | 
 |       assertFalse(Base.prototype.hasOwnProperty(ownSetter)); | 
 |     }, | 
 |     mStrict() { | 
 |       'use strict'; | 
 |       assertEquals(42, this[ownReadOnly]); | 
 |       assertThrows(() => {super[ownReadOnly] = 55}, TypeError); | 
 |       assertSame(undefined, super[ownReadOnly]); | 
 |       assertEquals(42, this[ownReadOnly]); | 
 |       assertFalse(Base.prototype.hasOwnProperty(ownReadOnly)); | 
 |  | 
 |       assertEquals(15, this[ownReadonlyAccessor]); | 
 |       assertThrows(() => {super[ownReadonlyAccessor] = 25}, TypeError); | 
 |       assertSame(undefined, super[ownReadonlyAccessor]); | 
 |       assertEquals(15, this[ownReadonlyAccessor]); | 
 |       assertFalse(Base.prototype.hasOwnProperty(ownReadonlyAccessor)); | 
 |  | 
 |       assertThrows(() => {super[ownSetter] = 35}, TypeError); | 
 |       assertSame(undefined, super[ownSetter]); | 
 |       var descr = Object.getOwnPropertyDescriptor(this, ownSetter); | 
 |       assertTrue('set' in descr); | 
 |       assertFalse(Base.prototype.hasOwnProperty(ownSetter)); | 
 |     }, | 
 |   }; | 
 |  | 
 |   var d = new Derived(); | 
 |   Object.defineProperty(d, ownReadOnly, { | 
 |     value: 42, | 
 |     writable: false, | 
 |     configurable: true | 
 |   }); | 
 |   Object.defineProperty(d, ownSetter, { | 
 |     set: function() { assertUnreachable(); }, | 
 |     configurable: true | 
 |   }); | 
 |   Object.defineProperty(d, ownReadonlyAccessor, { | 
 |     get: function() { return 15; }, | 
 |     configurable: true | 
 |   }); | 
 |  | 
 |   d.mSloppy(); | 
 |  | 
 |   var d = new Derived(); | 
 |   Object.defineProperty(d, ownReadOnly, { | 
 |     value: 42, | 
 |     writable: false, | 
 |     configurable: true | 
 |   }); | 
 |   Object.defineProperty(d, ownSetter, { | 
 |     set: function() { assertUnreachable(); }, | 
 |     configurable: true | 
 |   }); | 
 |   Object.defineProperty(d, ownReadonlyAccessor, { | 
 |     get: function() { return 15; }, | 
 |     configurable: true | 
 |   }); | 
 |   d.mStrict(); | 
 | } | 
 | TestKeyedSetterCreatingOwnPropertiesReconfigurable('ownReadOnly', | 
 |                                                    'ownReadonlyAccessor', | 
 |                                                    'ownSetter'); | 
 | TestKeyedSetterCreatingOwnPropertiesReconfigurable(42, 43, 44); | 
 |  | 
 |  | 
 | function TestKeyedSetterCreatingOwnPropertiesNonConfigurable( | 
 |     ownReadOnly, ownReadonlyAccessor, ownSetter) { | 
 |   function Base() {} | 
 |   function Derived() {} | 
 |   Derived.prototype = { | 
 |     __proto__: Base.prototype, | 
 |     mSloppy() { | 
 |       assertEquals(42, this[ownReadOnly]); | 
 |       super[ownReadOnly] = 55; | 
 |       assertEquals(42, this[ownReadOnly]); | 
 |       var descr = Object.getOwnPropertyDescriptor(this, ownReadOnly); | 
 |       assertEquals(42, descr.value); | 
 |       assertFalse(descr.configurable); | 
 |       assertFalse(descr.enumerable); | 
 |       assertFalse(descr.writable); | 
 |       assertFalse(Base.prototype.hasOwnProperty(ownReadOnly)); | 
 |  | 
 |       assertEquals(15, this[ownReadonlyAccessor]); | 
 |       super[ownReadonlyAccessor] = 25; | 
 |       assertSame(undefined, super[ownReadonlyAccessor]); | 
 |       assertEquals(15, this[ownReadonlyAccessor]); | 
 |       var descr = Object.getOwnPropertyDescriptor(this, ownReadonlyAccessor); | 
 |       assertFalse(descr.configurable); | 
 |       assertFalse(descr.enumerable); | 
 |       assertFalse(Base.prototype.hasOwnProperty(ownReadonlyAccessor)); | 
 |  | 
 |       super[ownSetter] = 35; | 
 |       var descr = Object.getOwnPropertyDescriptor(this, ownSetter); | 
 |       assertFalse(descr.configurable); | 
 |       assertFalse(descr.enumerable); | 
 |       assertFalse(Base.prototype.hasOwnProperty(ownSetter)); | 
 |     }, | 
 |     mStrict() { | 
 |       'use strict'; | 
 |       var ex; | 
 |       assertEquals(42, this[ownReadOnly]); | 
 |       try { | 
 |         super[ownReadOnly] = 55; | 
 |       } catch (e) { | 
 |         ex = e; | 
 |       } | 
 |       assertInstanceof(ex, TypeError); | 
 |       assertEquals( | 
 |           "Cannot assign to read only property '" + ownReadOnly + | 
 |               "' of object '#<Base>'", | 
 |           ex.message); | 
 |       assertEquals(42, this[ownReadOnly]); | 
 |  | 
 |       ex = null; | 
 |       assertEquals(15, this[ownReadonlyAccessor]); | 
 |       try { | 
 |         super[ownReadonlyAccessor] = 25; | 
 |       } catch (e) { | 
 |         ex = e; | 
 |       } | 
 |       assertInstanceof(ex, TypeError); | 
 |       assertEquals('Cannot redefine property: ' + ownReadonlyAccessor, | 
 |                    ex.message); | 
 |       assertEquals(15, this[ownReadonlyAccessor]); | 
 |  | 
 |       ex = null; | 
 |       try { | 
 |         super[ownSetter] = 35; | 
 |       } catch (e) { | 
 |         ex = e; | 
 |       } | 
 |       assertInstanceof(ex, TypeError); | 
 |       assertEquals('Cannot redefine property: ' + ownSetter, ex.message); | 
 |     } | 
 |   }; | 
 |  | 
 |   var d = new Derived(); | 
 |   Object.defineProperty(d, ownReadOnly, { value : 42, writable : false }); | 
 |   Object.defineProperty(d, ownSetter, | 
 |       { set : function() { assertUnreachable(); } }); | 
 |   Object.defineProperty(d, ownReadonlyAccessor, | 
 |       { get : function() { return 15; }}); | 
 |   d.mSloppy(); | 
 |   d.mStrict(); | 
 | } | 
 | TestKeyedSetterCreatingOwnPropertiesNonConfigurable('ownReadOnly', | 
 |     'ownReadonlyAccessor', 'ownSetter'); | 
 | TestKeyedSetterCreatingOwnPropertiesNonConfigurable(42, 43, 44); | 
 |  | 
 |  | 
 | (function TestSetterNoProtoWalk() { | 
 |   function Base() {} | 
 |   function Derived() {} | 
 |   var getCalled; | 
 |   var setCalled; | 
 |   Derived.prototype = { | 
 |     __proto__: Base.prototype, | 
 |     get x() { getCalled++; return 42; }, | 
 |     set x(v) { setCalled++; }, | 
 |     mSloppy() { | 
 |       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); | 
 |     }, | 
 |     mStrict() { | 
 |       '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); | 
 |     } | 
 |   }; | 
 |  | 
 |   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++; }, | 
 |     mSloppy() { | 
 |       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); | 
 |     }, | 
 |     mStrict() { | 
 |       '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); | 
 |     } | 
 |   }; | 
 |  | 
 |   new Derived().mSloppy(); | 
 |   new Derived().mStrict(); | 
 | }()); | 
 |  | 
 |  | 
 | (function TestKeyedNumericSetterNoProtoWalk() { | 
 |   var x = 42; | 
 |   function Base() {} | 
 |   function Derived() {} | 
 |   var getCalled; | 
 |   var setCalled; | 
 |   Derived.prototype = { | 
 |     __proto__: Base.prototype, | 
 |     mSloppy() { | 
 |       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); | 
 |     }, | 
 |     mStrict() { | 
 |       '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); | 
 |     } | 
 |   }; | 
 |  | 
 |   Object.defineProperty(Derived.prototype, x, { | 
 |     get: function() { getCalled++; return 42; }, | 
 |     set: function(v) { setCalled++; } | 
 |   }); | 
 |  | 
 |   new Derived().mSloppy(); | 
 |   new Derived().mStrict(); | 
 | }()); | 
 |  | 
 |  | 
 | (function TestSetterDoesNotReconfigure() { | 
 |   function Base() {} | 
 |   function Derived() {} | 
 |   Derived.prototype = { | 
 |     __proto__: Derived.prototype, | 
 |     mStrict(){ | 
 |       '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); | 
 |     }, | 
 |     mSloppy(){ | 
 |       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); | 
 |     } | 
 |   }; | 
 |  | 
 |   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, | 
 |     mStrict(){ | 
 |       '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); | 
 |     }, | 
 |     mSloppy(){ | 
 |       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); | 
 |     } | 
 |   }; | 
 |  | 
 |   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, | 
 |     mStrict(){ | 
 |       '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); | 
 |     }, | 
 |     mSloppy(){ | 
 |       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); | 
 |     } | 
 |   }; | 
 |  | 
 |   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, | 
 |     testCounts() { | 
 |       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); | 
 |     } | 
 |   }; | 
 |   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, | 
 |     testCounts() { | 
 |       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); | 
 |     } | 
 |   }; | 
 |   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, | 
 |     testCounts() { | 
 |       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); | 
 |     } | 
 |   }; | 
 |   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, | 
 |     mSloppy() { | 
 |       assertEquals(27, super.x); | 
 |       assertEquals(27, this.x); | 
 |       super.x = 10; | 
 |       assertEquals(27, super.x); | 
 |       assertEquals(27, this.x); | 
 |     }, | 
 |     mStrict() { | 
 |       'use strict'; | 
 |       assertEquals(27, super.x); | 
 |       assertEquals(27, this.x); | 
 |       var ex = null; | 
 |       try { super.x = 10; } catch(e) { ex = e; } | 
 |       assertInstanceof(ex, TypeError); | 
 |       assertEquals(27, super.x); | 
 |       assertEquals(27, this.x); | 
 |     } | 
 |   }; | 
 |   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, | 
 |     mSloppy() { | 
 |       assertEquals(27, super[x]); | 
 |       assertEquals(27, this[x]); | 
 |       super[x] = 10; | 
 |       assertEquals(27, super[x]); | 
 |       assertEquals(27, this[x]); | 
 |     }, | 
 |     mStrict() { | 
 |       'use strict'; | 
 |       assertEquals(27, super[x]); | 
 |       assertEquals(27, this[x]); | 
 |       var ex = null; | 
 |       try { super[x] = 10; } catch(e) { ex = e; } | 
 |       assertInstanceof(ex, TypeError); | 
 |       assertEquals(27, super[x]); | 
 |       assertEquals(27, this[x]); | 
 |     } | 
 |   }; | 
 |   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, | 
 |     mSloppy() { | 
 |       assertEquals(27, super[x]); | 
 |       assertEquals(27, this[x]); | 
 |       super[x] = 10; | 
 |       assertEquals(27, super[x]); | 
 |       assertEquals(27, this[x]); | 
 |     }, | 
 |     mStrict() { | 
 |       'use strict'; | 
 |       assertEquals(27, super[x]); | 
 |       assertEquals(27, this[x]); | 
 |       var ex = null; | 
 |       try { super[x] = 10; } catch(e) { ex = e; } | 
 |       assertInstanceof(ex, TypeError); | 
 |       assertEquals(27, super[x]); | 
 |       assertEquals(27, this[x]); | 
 |     } | 
 |   }; | 
 |   new Derived().mSloppy(); | 
 |   new Derived().mStrict(); | 
 | }()); | 
 |  | 
 |  | 
 | (function TestSuperCall() { | 
 |   'use strict'; | 
 |  | 
 |   var baseCalled = 0; | 
 |   var derivedCalled = 0; | 
 |   var derivedDerivedCalled = 0; | 
 |  | 
 |   class Base { | 
 |     constructor() { | 
 |       baseCalled++; | 
 |     } | 
 |   } | 
 |  | 
 |   class Derived extends Base { | 
 |     constructor() { | 
 |       let r = super(); | 
 |       assertEquals(this, r); | 
 |       derivedCalled++; | 
 |     } | 
 |   } | 
 |  | 
 |   assertEquals(Base, Base.prototype.constructor); | 
 |   assertEquals(Base.prototype, Derived.prototype.__proto__); | 
 |  | 
 |   baseCalled = 0; | 
 |   derivedCalled = 0; | 
 |   new Derived(); | 
 |   assertEquals(1, baseCalled); | 
 |   assertEquals(1, derivedCalled); | 
 |  | 
 |   class DerivedDerived extends Derived { | 
 |     constructor() { | 
 |       let r = super(); | 
 |       assertEquals(this, r); | 
 |       derivedDerivedCalled++; | 
 |     } | 
 |   } | 
 |  | 
 |   baseCalled = 0; | 
 |   derivedCalled = 0; | 
 |   derivedDerivedCalled = 0; | 
 |   new DerivedDerived(); | 
 |   assertEquals(1, baseCalled); | 
 |   assertEquals(1, derivedCalled); | 
 |   assertEquals(1, derivedDerivedCalled); | 
 |  | 
 |   class Base2 { | 
 |     constructor(v) { | 
 |       this.fromBase = v; | 
 |     } | 
 |   } | 
 |   class Derived2 extends Base2 { | 
 |     constructor(v1, v2) { | 
 |       let r = super(v1); | 
 |       assertEquals(this, r); | 
 |       this.fromDerived = v2; | 
 |     } | 
 |   } | 
 |  | 
 |   var d = new Derived2("base", "derived"); | 
 |   assertEquals("base", d.fromBase); | 
 |   assertEquals("derived", d.fromDerived); | 
 |  | 
 |   var calls = 0; | 
 |   class G { | 
 |     constructor() { | 
 |       calls++; | 
 |     } | 
 |   } | 
 |  | 
 |   class F extends Object { | 
 |     constructor() { | 
 |       super(); | 
 |     } | 
 |   } | 
 |   F.__proto__ = G; | 
 |   new F(); | 
 |   assertEquals(1, calls); | 
 |   F.__proto__ = function() {}; | 
 |   new F(); | 
 |   assertEquals(1, calls); | 
 | }()); | 
 |  | 
 |  | 
 | (function TestExtendsObject() { | 
 |   'use strict'; | 
 |   class F extends Object { } | 
 |   var f = new F(42); | 
 |  | 
 |   assertInstanceof(f, F); | 
 |   assertInstanceof(f, Object); | 
 | }()); | 
 |  | 
 |  | 
 | (function TestSuperCallErrorCases() { | 
 |   'use strict'; | 
 |   class T extends Object { | 
 |     constructor() { | 
 |       super(); | 
 |     } | 
 |   } | 
 |  | 
 |   T.__proto__ = null; | 
 |   assertThrows(function() { new T(); }, TypeError); | 
 | }()); | 
 |  | 
 |  | 
 | (function TestSuperPropertyInEval() { | 
 |   'use strict'; | 
 |   let y = 3; | 
 |   class Base { | 
 |     m() { return 1; } | 
 |     get x() { return 2; } | 
 |   } | 
 |   class Derived extends Base { | 
 |     evalM() { | 
 |       assertEquals(1, eval('super.m()')); | 
 |     } | 
 |     evalX() { | 
 |       assertEquals(2, eval('super.x')); | 
 |     } | 
 |     globalEval1() { | 
 |       assertThrows('super.x', SyntaxError); | 
 |       assertThrows('super.m()', SyntaxError); | 
 |     } | 
 |     globalEval2() { | 
 |       super.x; | 
 |       assertThrows('super.x', SyntaxError); | 
 |       assertThrows('super.m()', SyntaxError); | 
 |     } | 
 |   } | 
 |   let d = new Derived(); | 
 |   d.globalEval1(); | 
 |   d.globalEval2(); | 
 |   d.evalM(); | 
 |   d.evalX(); | 
 | })(); | 
 |  | 
 |  | 
 | (function TestSuperPropertyInArrow() { | 
 |   'use strict'; | 
 |   let y = 3; | 
 |   class Base { | 
 |     m() { return 1; } | 
 |     get x() { return 2; } | 
 |   } | 
 |   class Derived extends Base { | 
 |     arrow() { | 
 |       assertSame(super.x, (() => super.x)()); | 
 |       assertSame(super.m(), (() => super.m())()); | 
 |       return (() => super.m())(); | 
 |     } | 
 |   } | 
 |   let d = new Derived(); | 
 |   assertSame(1, d.arrow()); | 
 | })(); | 
 |  | 
 |  | 
 | (function TestSuperInOtherScopes() { | 
 |   var p = {x: 99}; | 
 |   var o0 = {__proto__: p, f() { return eval("'use strict'; super.x") }}; | 
 |   assertEquals(p.x, o0.f()); | 
 |   var o1 = {__proto__: p, f() { with ({}) return super.x }}; | 
 |   assertEquals(p.x, o1.f()); | 
 |   var o2 = {__proto__: p, f({a}) { return super.x }}; | 
 |   assertEquals(p.x, o2.f({})); | 
 |   var o3 = {__proto__: p, f(...a) { return super.x }}; | 
 |   assertEquals(p.x, o3.f()); | 
 |   var o4 = {__proto__: p, f() { 'use strict'; { let x; return super.x } }}; | 
 |   assertEquals(p.x, o4.f()); | 
 | })(); | 
 |  | 
 |  | 
 | (function TestSuperCallInOtherScopes() { | 
 |   class C {constructor() { this.x = 99 }} | 
 |   class D0 extends C {constructor() { eval("'use strict'; super()") }} | 
 |   assertEquals(99, (new D0).x); | 
 |   class D2 extends C {constructor({a}) { super() }} | 
 |   assertEquals(99, (new D2({})).x); | 
 |   class D3 extends C {constructor(...a) { super() }} | 
 |   assertEquals(99, (new D3()).x); | 
 |   class D4 extends C {constructor() { { let x; super() } }} | 
 |   assertEquals(99, (new D4).x); | 
 | })(); | 
 |  | 
 |  | 
 | (function TestSuperCallInEval() { | 
 |   'use strict'; | 
 |   class Base { | 
 |     constructor(x) { | 
 |       this.x = x; | 
 |     } | 
 |   } | 
 |   class Derived extends Base { | 
 |     constructor(x) { | 
 |       let r = eval('super(x)'); | 
 |       assertEquals(this, r); | 
 |     } | 
 |   } | 
 |   let d = new Derived(42); | 
 |   assertSame(42, d.x); | 
 | })(); | 
 |  | 
 |  | 
 | (function TestSuperCallInArrow() { | 
 |   'use strict'; | 
 |   class Base { | 
 |     constructor(x) { | 
 |       this.x = x; | 
 |     } | 
 |   } | 
 |   class Derived extends Base { | 
 |     constructor(x) { | 
 |       let r = (() => super(x))(); | 
 |       assertEquals(this, r); | 
 |     } | 
 |   } | 
 |   let d = new Derived(42); | 
 |   assertSame(42, d.x); | 
 | })(); | 
 |  | 
 |  | 
 | (function TestSuperCallEscapes() { | 
 |   'use strict'; | 
 |   class Base { | 
 |     constructor(x) { | 
 |       this.x = x; | 
 |     } | 
 |   } | 
 |  | 
 |   let f; | 
 |   class Derived extends Base { | 
 |     constructor() { | 
 |       f = () => super(2); | 
 |     } | 
 |   } | 
 |   assertThrows(function() { | 
 |     new Derived(); | 
 |   }, ReferenceError); | 
 |  | 
 |   let o = f(); | 
 |   assertEquals(2, o.x); | 
 |   assertInstanceof(o, Derived); | 
 |  | 
 |   assertThrows(function() { | 
 |     f(); | 
 |   }, ReferenceError); | 
 | })(); | 
 |  | 
 |  | 
 | (function TestSuperCallInLoop() { | 
 |   'use strict'; | 
 |   class Base { | 
 |     constructor(x) { | 
 |       this.x = x; | 
 |     } | 
 |   } | 
 |   class Derived extends Base { | 
 |     constructor(x, n) { | 
 |       for (var i = 0; i < n; ++i) { | 
 |         super(x); | 
 |       } | 
 |     } | 
 |   } | 
 |  | 
 |   let o = new Derived(23, 1); | 
 |   assertEquals(23, o.x); | 
 |   assertInstanceof(o, Derived); | 
 |  | 
 |   assertThrows("new Derived(42, 0)", ReferenceError); | 
 |   assertThrows("new Derived(65, 2)", ReferenceError); | 
 | })(); | 
 |  | 
 |  | 
 | (function TestSuperCallReentrant() { | 
 |   'use strict'; | 
 |   class Base { | 
 |     constructor(fun) { | 
 |       this.x = fun(); | 
 |     } | 
 |   } | 
 |   class Derived extends Base { | 
 |     constructor(x) { | 
 |       let f = () => super(() => x) | 
 |       super(f); | 
 |     } | 
 |   } | 
 |   assertThrows("new Derived(23)", ReferenceError); | 
 | })(); | 
 |  | 
 |  | 
 | (function TestSuperCallSpreadInEval() { | 
 |   'use strict'; | 
 |   class Base { | 
 |     constructor(x) { | 
 |       this.x = x; | 
 |     } | 
 |   } | 
 |   class Derived extends Base { | 
 |     constructor(x) { | 
 |       let r = eval('super(...[x])'); | 
 |       assertEquals(this, r); | 
 |     } | 
 |   } | 
 |   let d = new Derived(42); | 
 |   assertSame(42, d.x); | 
 | })(); | 
 |  | 
 |  | 
 | (function TestSuperCallSpreadInArrow() { | 
 |   'use strict'; | 
 |   class Base { | 
 |     constructor(x) { | 
 |       this.x = x; | 
 |     } | 
 |   } | 
 |   class Derived extends Base { | 
 |     constructor(x) { | 
 |       let r = (() => super(...[x]))(); | 
 |       assertEquals(this, r); | 
 |     } | 
 |   } | 
 |   let d = new Derived(42); | 
 |   assertSame(42, d.x); | 
 | })(); | 
 |  | 
 | (function TestNullSuperPropertyLoad() { | 
 |   var obj = { | 
 |     __proto__: null, | 
 |     named() { return super.x }, | 
 |     keyed() { return super[5] } | 
 |   }; | 
 |   assertThrows(obj.named, TypeError); | 
 |   assertThrows(obj.keyed, TypeError); | 
 |   class C extends null { | 
 |     named() { return super.x } | 
 |     keyed() { return super[5] } | 
 |   } | 
 |   assertThrows(C.prototype.named, TypeError); | 
 |   assertThrows(C.prototype.keyed, TypeError); | 
 | })(); | 
 |  | 
 | (function TestNullSuperPropertyStore() { | 
 |   var obj = { | 
 |     __proto__: null, | 
 |     named() { super.x = 42 }, | 
 |     keyed() { super[5] = 42 } | 
 |   }; | 
 |   assertThrows(obj.named, TypeError); | 
 |   assertThrows(obj.keyed, TypeError); | 
 |   class C extends null { | 
 |     named() { super.x = 42 } | 
 |     keyed() { super[5] = 42 } | 
 |   } | 
 |   assertThrows(C.prototype.named, TypeError); | 
 |   assertThrows(C.prototype.keyed, TypeError); | 
 | })(); |