1// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Flags: --allow-natives-syntax
6
7(function TestSuperNamedLoads() {
8  function Base() { }
9  function fBase() { }
10  Base.prototype = {
11    f() {
12      return "Base " + this.toString();
13    },
14    x: 15,
15    toString() {
16      return "this is Base";
17    }
18  };
19
20  function Derived() {
21    this.derivedDataProperty = "xxx";
22  }
23  Derived.prototype = {
24    __proto__: Base.prototype,
25    toString() { return "this is Derived"; },
26    x: 27,
27    f() {
28      assertEquals("Base this is Derived", super.f());
29      var a = super.x;
30      assertEquals(15, a);
31      assertEquals(15, super.x);
32      assertEquals(27, this.x);
33      return "Derived";
34    }
35  };
36
37  assertEquals("Base this is Base", new Base().f());
38  assertEquals("Derived", new Derived().f());
39}());
40
41
42(function TestSuperKeyedLoads() {
43  'use strict';
44
45  var x = 'x';
46  var derivedDataProperty = 'derivedDataProperty';
47  var f = 'f';
48
49  class Base {
50    f() {
51      return "Base " + this.toString();
52    }
53    toString() {
54      return "this is Base";
55    }
56  }
57
58  Base.prototype[x] = 15;
59
60  function Derived() {
61    this[derivedDataProperty] = "xxx";
62  }
63  Derived.prototype = {
64    __proto__: Base.prototype,
65    toString() { return "this is Derived"; },
66    x: 27,
67    f() {
68      assertEquals("Base this is Derived", super[f]());
69      var a = super[x];
70      assertEquals(15, a);
71      assertEquals(15, super[x]);
72      assertEquals(27, this[x]);
73      return "Derived";
74    }
75  };
76
77  assertEquals("Base this is Base", new Base().f());
78  assertEquals("Derived", new Derived().f());
79}());
80
81
82(function TestSuperKeywordNonMethod() {
83  'use strict';
84
85  class C {
86    f() {
87      super.unknown();
88    }
89  }
90
91  assertThrows(function() {
92    new C().f();
93  }, TypeError);
94}());
95
96
97(function TestGetter() {
98  function Base() {}
99  var derived;
100  Base.prototype = {
101    constructor: Base,
102    get x() {
103      assertSame(this, derived);
104      return this._x;
105    },
106    _x: 'base'
107  };
108
109  function Derived() {}
110  Derived.__proto__ = Base;
111  Derived.prototype = {
112    __proto__: Base.prototype,
113    constructor: Derived,
114    _x: 'derived',
115    testGetter() {
116      return super.x;
117    },
118    testGetterStrict() {
119      'use strict';
120      return super.x;
121    }
122  };
123
124  derived = new Derived();
125  assertEquals('derived', derived.testGetter());
126  derived = new Derived();
127  assertEquals('derived', derived.testGetterStrict());
128}());
129
130
131(function TestGetterKeyed() {
132  var x = 'x';
133  function Base() {}
134  var derived;
135  Base.prototype = {
136    constructor: Base,
137    get x() {
138      assertSame(this, derived);
139      return this._x;
140    },
141    _x: 'base'
142  };
143
144  function Derived() {}
145  Derived.__proto__ = Base;
146  Derived.prototype = {
147    __proto__: Base.prototype,
148    constructor: Derived,
149    _x: 'derived',
150    testGetter() {
151      return super[x];
152    },
153    testGetterStrict() {
154      'use strict';
155      return super[x];
156    },
157    testGetterWithToString() {
158      var toStringCalled;
159      var o = { toString: function() {
160        toStringCalled++;
161        return 'x';
162      } };
163
164      toStringCalled = 0;
165      assertEquals('derived', super[o]);
166      assertEquals(1, toStringCalled);
167
168      var eToThrow = new Error();
169      var oThrowsInToString = { toString: function() {
170        throw eToThrow;
171      } };
172
173      var ex = null;
174      try {
175        super[oThrowsInToString];
176      } catch(e) { ex = e }
177      assertEquals(eToThrow, ex);
178
179      var oReturnsNumericString = { toString: function() {
180        return "1";
181      } };
182
183      assertEquals(undefined, super[oReturnsNumericString]);
184      assertEquals(undefined, super[1]);
185    }
186  };
187
188  derived = new Derived();
189  assertEquals('derived', derived.testGetter());
190  derived = new Derived();
191  assertEquals('derived', derived.testGetterStrict());
192  derived = new Derived();
193  derived.testGetterWithToString();
194}());
195
196
197(function TestGetterNumericKeyed() {
198  var x = 42;
199  function Base() {}
200  var derived;
201  Base.prototype = {
202    constructor: Base,
203    _x: 'base'
204  };
205
206  Object.defineProperty(Base.prototype, x, { get: function() {
207      assertSame(this, derived);
208      return this._x;
209  }});
210
211  function Derived() {}
212  Derived.__proto__ = Base;
213  Derived.prototype = {
214    __proto__: Base.prototype,
215    constructor: Derived,
216    _x: 'derived',
217    testGetter() {
218      return super[x];
219    },
220    testGetterStrict() {
221      'use strict';
222      return super[x];
223    },
224    testGetterWithToString() {
225      var toStringCalled;
226      var o = {
227        toString: function() {
228          toStringCalled++;
229          return '42';
230        }
231      };
232
233      toStringCalled = 0;
234      assertEquals('derived', super[o]);
235      assertEquals(1, toStringCalled);
236
237      var eToThrow = new Error();
238      var oThrowsInToString = {
239        toString: function() {
240          throw eToThrow;
241        }
242      };
243
244      var ex = null;
245      try {
246        super[oThrowsInToString];
247      } catch(e) { ex = e }
248      assertEquals(eToThrow, ex);
249
250      var oReturnsNumericString = {
251        toString: function() {
252          return "42";
253        }
254      };
255
256      assertEquals('derived', super[oReturnsNumericString]);
257      assertEquals('derived', super[42]);
258    }
259  };
260
261  derived = new Derived();
262  assertEquals('derived', derived.testGetter());
263  derived = new Derived();
264  assertEquals('derived', derived.testGetterStrict());
265  derived = new Derived();
266  derived.testGetterWithToString();
267}());
268
269
270(function TestSetter() {
271  function Base() {}
272  Base.prototype = {
273    constructor: Base,
274    get x() {
275      return this._x;
276    },
277    set x(v) {
278      this._x = v;
279    },
280    _x: 'base'
281  };
282
283  function Derived() {}
284  Derived.__proto__ = Base;
285  Derived.prototype = {
286    __proto__: Base.prototype,
287    constructor: Derived,
288    _x: 'derived',
289    testSetter() {
290      assertEquals('foobar', super.x = 'foobar');
291      assertEquals('foobarabc', super.x += 'abc');
292    },
293    testSetterStrict() {
294      'use strict';
295      assertEquals('foobar', super.x = 'foobar');
296      assertEquals('foobarabc', super.x += 'abc');
297    }
298  };
299
300  var d = new Derived();
301  d.testSetter();
302  assertEquals('base', Base.prototype._x);
303  assertEquals('foobarabc', d._x);
304  d._x = '';
305
306  d.testSetterStrict();
307  assertEquals('base', Base.prototype._x);
308  assertEquals('foobarabc', d._x);
309}());
310
311
312(function TestSetterNumericKeyed() {
313  var x = 42;
314  function Base() {}
315  Base.prototype = {
316    constructor: Base,
317    _x: 'base'
318  };
319
320  Object.defineProperty(Base.prototype, x,
321    { get: function() { return this._x; },
322      set: function(v) { this._x = v; }
323    });
324
325  function Derived() {}
326  Derived.__proto__ = Base;
327  Derived.prototype = {
328    __proto__: Base.prototype,
329    constructor: Derived,
330    _x: 'derived',
331    testSetter() {
332      assertEquals('foobar', super[x] = 'foobar');
333      assertEquals('foobarabc', super[x] += 'abc');
334    },
335    testSetterStrict() {
336      'use strict';
337      assertEquals('foobar', super[x] = 'foobar');
338      assertEquals('foobarabc', super[x] += 'abc');
339    },
340    testSetterWithToString() {
341      var toStringCalled;
342      var o = {
343        toString: function() {
344          toStringCalled++;
345          return x;
346        }
347      };
348
349      toStringCalled = 0;
350      super[o] = 'set';
351      assertEquals(1, toStringCalled);
352      assertEquals('set', this._x);
353
354      var eToThrow = new Error();
355      var oThrowsInToString = {
356        toString: function() {
357          throw eToThrow;
358        }
359      };
360
361      var ex = null;
362      try {
363        super[oThrowsInToString] = 'xyz';
364      } catch(e) { ex = e }
365      assertEquals(eToThrow, ex);
366      assertEquals('set', this._x);
367    }
368  };
369
370  var d = new Derived();
371  d.testSetter();
372  assertEquals('base', Base.prototype._x);
373  assertEquals('foobarabc', d._x);
374  d._x = '';
375
376  d.testSetterStrict();
377  assertEquals('base', Base.prototype._x);
378  assertEquals('foobarabc', d._x);
379
380  d = new Derived();
381  d.testSetterWithToString();
382}());
383
384
385(function TestSetterKeyed() {
386  var x = 'x';
387  function Base() {}
388  Base.prototype = {
389    constructor: Base,
390    get x() {
391      return this._x;
392    },
393    set x(v) {
394      this._x = v;
395    },
396    _x: 'base'
397  };
398
399  function Derived() {}
400  Derived.__proto__ = Base;
401  Derived.prototype = {
402    __proto__: Base.prototype,
403    constructor: Derived,
404    _x: 'derived',
405    testSetter() {
406      assertEquals('foobar', super[x] = 'foobar');
407      assertEquals('foobarabc', super[x] += 'abc');
408    },
409    testSetterStrict() {
410      'use strict';
411      assertEquals('foobar', super[x] = 'foobar');
412      assertEquals('foobarabc', super[x] += 'abc');
413    },
414    testSetterWithToString() {
415      var toStringCalled;
416      var o = {
417        toString: function() {
418          toStringCalled++;
419          return 'x';
420        }
421      };
422
423      toStringCalled = 0;
424      super[o] = 'set';
425      assertEquals(1, toStringCalled);
426      assertEquals('set', this._x);
427
428      var eToThrow = new Error();
429      var oThrowsInToString = {
430        toString: function() {
431          throw eToThrow;
432        }
433      };
434
435      var ex = null;
436      try {
437        super[oThrowsInToString] = 'xyz';
438      } catch(e) { ex = e }
439      assertEquals(eToThrow, ex);
440      assertEquals('set', this._x);
441
442      var oReturnsNumericString = {
443        toString: function() {
444          return "1";
445        }
446      };
447
448      assertEquals('abc', super[oReturnsNumericString] = 'abc');
449
450      assertEquals('set', this._x);
451
452      assertEquals(10,  super[1] = 10);
453    }
454  };
455
456  var d = new Derived();
457  d.testSetter();
458  assertEquals('base', Base.prototype._x);
459  assertEquals('foobarabc', d._x);
460  d._x = '';
461  d.testSetterStrict();
462  assertEquals('base', Base.prototype._x);
463  assertEquals('foobarabc', d._x);
464
465  d = new Derived();
466  d.testSetterWithToString();
467}());
468
469
470(function TestSetterDataProperties() {
471  function Base() {}
472  Base.prototype = {
473    constructor: Base,
474    x: 'x from Base'
475  };
476
477  function Derived() {}
478  Derived.prototype = {
479    __proto__: Base.prototype,
480    constructor: Derived,
481    testSetter() {
482      assertEquals('x from Base', super.x);
483      super.x = 'data property';
484      assertEquals('x from Base', super.x);
485      assertEquals('data property', this.x);
486    }
487  };
488
489  new Derived().testSetter();
490}());
491
492
493(function TestKeyedSetterDataProperties() {
494  var x = 'x';
495  function Base() {}
496  Base.prototype = {
497    constructor: Base,
498    x: 'x from Base'
499  };
500
501  function Derived() {}
502  Derived.prototype = {
503    __proto__: Base.prototype,
504    constructor: Derived,
505    testSetter() {
506      assertEquals('x from Base', super[x]);
507      super[x] = 'data property';
508      assertEquals('x from Base', super[x]);
509      assertEquals('data property', this[x]);
510    }
511  };
512
513  new Derived().testSetter();
514}());
515
516
517(function TestKeyedNumericSetterDataProperties() {
518  var x = 42;
519  function Base() {}
520  Base.prototype = {
521    constructor: Base,
522    42: 'x from Base'
523  };
524
525  function Derived() {}
526  Derived.prototype = {
527    __proto__: Base.prototype,
528    constructor: Derived,
529    testSetter() {
530      assertEquals('x from Base', super[x]);
531      super[x] = 'data property';
532      assertEquals('x from Base', super[x]);
533      assertEquals('data property', this[x]);
534    }
535  };
536
537  new Derived().testSetter();
538}());
539
540
541(function TestAccessorsOnPrimitives() {
542  var getCalled = 0;
543  var setCalled = 0;
544  function Base() {}
545  Base.prototype = {
546    constructor: Base,
547    get x() {
548      getCalled++;
549      return 1;
550    },
551    set x(v) {
552      setCalled++;
553      return v;
554    },
555  };
556
557  function Derived() {}
558  Derived.prototype = {
559    __proto__: Base.prototype,
560    constructor: Derived,
561    testSetter() {
562      setCalled = 0;
563      getCalled = 0;
564      assertEquals('object', typeof this);
565      assertInstanceof(this, Number)
566      assertEquals(42, this.valueOf());
567      assertEquals(1, super.x);
568      assertEquals(1, getCalled);
569      assertEquals(0, setCalled);
570
571      assertEquals(5, super.x = 5);
572      assertEquals(1, getCalled);
573      assertEquals(1, setCalled);
574
575      assertEquals(6, super.x += 5);
576      assertEquals(2, getCalled);
577      assertEquals(2, setCalled);
578
579      super.newProperty = 15;
580      assertEquals(15, this.newProperty);
581      assertEquals(undefined, super.newProperty);
582    },
583    testSetterStrict() {
584      'use strict';
585      getCalled = 0;
586      setCalled = 0;
587      assertTrue(42 === this);
588
589      assertEquals(1, super.x);
590      assertEquals(1, getCalled);
591      assertEquals(0, setCalled);
592
593      assertEquals(5, super.x = 5);
594      assertEquals(1, getCalled);
595      assertEquals(1, setCalled);
596
597      assertEquals(6, super.x += 5);
598      assertEquals(2, getCalled);
599      assertEquals(2, setCalled);
600
601      var ex;
602      try {
603        super.newProperty = 15;
604      } catch (e) { ex = e; }
605      assertInstanceof(ex, TypeError);
606    }
607  }
608
609  Derived.prototype.testSetter.call(42);
610  Derived.prototype.testSetterStrict.call(42);
611
612  function DerivedFromString() {}
613  DerivedFromString.prototype = {
614    __proto__: String.prototype,
615    f() {
616      'use strict';
617      assertTrue(42 === this);
618      assertEquals(String.prototype.toString, super.toString);
619      var ex;
620      try {
621        super.toString();
622      } catch(e) { ex = e; }
623
624      assertInstanceof(ex, TypeError);
625    }
626  };
627
628  DerivedFromString.prototype.f.call(42);
629}());
630
631
632(function TestKeyedAccessorsOnPrimitives() {
633  var x = 'x';
634  var newProperty = 'newProperty';
635  var toString = 'toString';
636  var getCalled = 0;
637  var setCalled = 0;
638  function Base() {}
639  Base.prototype = {
640    constructor: Base,
641    get x() {
642      getCalled++;
643      return 1;
644    },
645    set x(v) {
646      setCalled++;
647      return v;
648    },
649  };
650
651  function Derived() {}
652  Derived.prototype = {
653    __proto__: Base.prototype,
654    constructor: Derived,
655    testSetter() {
656      setCalled = 0;
657      getCalled = 0;
658      assertEquals('object', typeof this);
659      assertInstanceof(this, Number)
660      assertEquals(42, this.valueOf());
661      assertEquals(1, super[x]);
662      assertEquals(1, getCalled);
663      assertEquals(0, setCalled);
664
665      assertEquals(5, super[x] = 5);
666      assertEquals(1, getCalled);
667      assertEquals(1, setCalled);
668
669      assertEquals(6, super[x] += 5);
670      assertEquals(2, getCalled);
671      assertEquals(2, setCalled);
672
673      super[newProperty] = 15;
674      assertEquals(15, this[newProperty]);
675      assertEquals(undefined, super[newProperty]);
676    },
677    testSetterStrict() {
678      'use strict';
679      getCalled = 0;
680      setCalled = 0;
681      assertTrue(42 === this);
682
683      assertEquals(1, super[x]);
684      assertEquals(1, getCalled);
685      assertEquals(0, setCalled);
686
687      assertEquals(5, super[x] = 5);
688      assertEquals(1, getCalled);
689      assertEquals(1, setCalled);
690
691      assertEquals(6, super[x] += 5);
692      assertEquals(2, getCalled);
693      assertEquals(2, setCalled);
694
695      var ex;
696      try {
697        super[newProperty] = 15;
698      } catch (e) { ex = e; }
699      assertInstanceof(ex,TypeError);
700    }
701  };
702
703  Derived.prototype.testSetter.call(42);
704  Derived.prototype.testSetterStrict.call(42);
705
706  function DerivedFromString() {}
707  DerivedFromString.prototype = {
708    __proto__: String.prototype,
709    f() {
710      'use strict';
711      assertTrue(42 === this);
712      assertEquals(String.prototype.toString, super[toString]);
713      var ex;
714      try {
715        super[toString]();
716      } catch(e) { ex = e; }
717
718      assertInstanceof(ex, TypeError);
719    }
720  };
721  DerivedFromString.prototype.f.call(42);
722}());
723
724
725(function TestNumericKeyedAccessorsOnPrimitives() {
726  var x = 42;
727  var newProperty = 43;
728  var getCalled = 0;
729  var setCalled = 0;
730  function Base() {}
731  Base.prototype = {
732    constructor: Base,
733  };
734
735  Object.defineProperty(Base.prototype, x, {
736    get: function() {
737      getCalled++;
738      return 1;
739    },
740    set: function(v) {
741      setCalled++;
742      return v;
743    }
744  });
745
746  function Derived() {}
747  Derived.prototype = {
748    __proto__: Base.prototype,
749    constructor: Derived,
750    testSetter() {
751      setCalled = 0;
752      getCalled = 0;
753      assertEquals('object', typeof this);
754      assertInstanceof(this, Number)
755      assertEquals(42, this.valueOf());
756      assertEquals(1, super[x]);
757      assertEquals(1, getCalled);
758      assertEquals(0, setCalled);
759
760      assertEquals(5, super[x] = 5);
761      assertEquals(1, getCalled);
762      assertEquals(1, setCalled);
763
764      assertEquals(6, super[x] += 5);
765      assertEquals(2, getCalled);
766      assertEquals(2, setCalled);
767
768      super[newProperty] = 15;
769      assertEquals(15, this[newProperty]);
770      assertEquals(undefined, super[newProperty]);
771    },
772    testSetterStrict() {
773      'use strict';
774      getCalled = 0;
775      setCalled = 0;
776      assertTrue(42 === this);
777
778      assertEquals(1, super[x]);
779      assertEquals(1, getCalled);
780      assertEquals(0, setCalled);
781
782      assertEquals(5, super[x] = 5);
783      assertEquals(1, getCalled);
784      assertEquals(1, setCalled);
785
786      assertEquals(6, super[x] += 5);
787      assertEquals(2, getCalled);
788      assertEquals(2, setCalled);
789
790      var ex;
791      try {
792        super[newProperty] = 15;
793      } catch (e) { ex = e; }
794      assertInstanceof(ex, TypeError);
795    }
796  };
797
798  Derived.prototype.testSetter.call(42);
799  Derived.prototype.testSetterStrict.call(42);
800}());
801
802
803(function TestKeyedNumericSetterOnExotics() {
804  function Base() {}
805  function Derived() {}
806  Derived.prototype = {
807    __proto__: Base.prototype,
808    callSetterOnArray() {
809      super[42] = 1;
810    },
811    callStrictSetterOnString() {
812      'use strict';
813      assertEquals('string', typeof this);
814      assertTrue('abcdef' === this);
815      var ex = null;
816      try {
817        super[5] = 'q';
818      } catch(e) { ex = e; }
819      assertInstanceof(ex, TypeError);
820
821      ex = null;
822      try {
823        super[1024] = 'q';
824      } catch(e) { ex = e; }
825      assertInstanceof(ex, TypeError);
826    }
827  };
828
829  var x = [];
830  assertEquals(0, x.length);
831  Derived.prototype.callSetterOnArray.call(x);
832  assertEquals(43, x.length);
833  assertEquals(1, x[42]);
834
835  var s = 'abcdef';
836  Derived.prototype.callStrictSetterOnString.call(s)
837}());
838
839
840(function TestSetterUndefinedProperties() {
841  function Base() {}
842  function Derived() {}
843  Derived.prototype = {
844    __proto__: Base.prototype,
845    mSloppy() {
846      assertEquals(undefined, super.x);
847      assertEquals(undefined, this.x);
848      super.x = 10;
849      assertEquals(10, this.x);
850      assertEquals(undefined, super.x);
851    },
852    mStrict() {
853      'use strict';
854      assertEquals(undefined, super.x);
855      assertEquals(undefined, this.x);
856      super.x = 10;
857      assertEquals(10, this.x);
858      assertEquals(undefined, super.x);
859    }
860  };
861
862  var d = new Derived();
863  d.mSloppy();
864  assertEquals(10, d.x);
865  var d1 = new Derived();
866  d1.mStrict();
867  assertEquals(10, d.x);
868}());
869
870
871(function TestKeyedSetterUndefinedProperties() {
872  var x = 'x';
873  function Base() {}
874  function Derived() {}
875  Derived.prototype = {
876    __proto__: Base.prototype,
877    mSloppy() {
878      assertEquals(undefined, super[x]);
879      assertEquals(undefined, this[x]);
880      super[x] = 10;
881      assertEquals(10, this[x]);
882      assertEquals(undefined, super[x]);
883    },
884    mStrict() {
885      'use strict';
886      assertEquals(undefined, super[x]);
887      assertEquals(undefined, this[x]);
888      super[x] = 10;
889      assertEquals(10, this[x]);
890      assertEquals(undefined, super[x]);
891    }
892  };
893  var d = new Derived();
894  d.mSloppy();
895  assertEquals(10, d.x);
896  var d1 = new Derived();
897  d1.mStrict();
898  assertEquals(10, d.x);
899}());
900
901
902(function TestKeyedNumericSetterUndefinedProperties() {
903  var x = 42;
904  function Base() {}
905  function Derived() {}
906  Derived.prototype = {
907    __proto__: Base.prototype,
908    mSloppy() {
909      assertEquals(undefined, super[x]);
910      assertEquals(undefined, this[x]);
911      super[x] = 10;
912      assertEquals(10, this[x]);
913      assertEquals(undefined, super[x]);
914    },
915    mStrict() {
916      'use strict';
917      assertEquals(undefined, super[x]);
918      assertEquals(undefined, this[x]);
919      super[x] = 10;
920      assertEquals(10, this[x]);
921      assertEquals(undefined, super[x]);
922    }
923  };
924  var d = new Derived();
925  d.mSloppy();
926  assertEquals(10, d[x]);
927  var d1 = new Derived();
928  d1.mStrict();
929  assertEquals(10, d[x]);
930}());
931
932
933(function TestSetterCreatingOwnPropertiesReconfigurable() {
934  function Base() {}
935  function Derived() {}
936  Derived.prototype = {
937    __proto__: Base.prototype,
938    mSloppy() {
939      assertEquals(42, this.ownReadOnly);
940      super.ownReadOnly = 55;
941      assertSame(undefined, super.ownReadOnly);
942      assertEquals(42, this.ownReadOnly);
943      assertFalse(Base.prototype.hasOwnProperty('ownReadOnly'));
944
945      assertEquals(15, this.ownReadonlyAccessor);
946      super.ownReadonlyAccessor = 25;
947      assertSame(undefined, super.ownReadonlyAccessor);
948      assertEquals(15, this.ownReadonlyAccessor);
949      assertFalse(Base.prototype.hasOwnProperty('ownReadonlyAccessor'));
950
951      super.ownSetter = 35;
952      assertSame(undefined, super.ownSetter);
953      var descr = Object.getOwnPropertyDescriptor(this, 'ownSetter');
954      assertTrue('set' in descr);
955      assertFalse(Base.prototype.hasOwnProperty('ownSetter'));
956    },
957    mStrict() {
958      'use strict';
959      assertEquals(42, this.ownReadOnly);
960      assertThrows(() => {super.ownReadOnly = 55}, TypeError);
961      assertSame(undefined, super.ownReadOnly);
962      assertEquals(42, this.ownReadOnly);
963      assertFalse(Base.prototype.hasOwnProperty('ownReadOnly'));
964
965      assertEquals(15, this.ownReadonlyAccessor);
966      assertThrows(() => {super.ownReadonlyAccessor = 25}, TypeError);
967      assertSame(undefined, super.ownReadonlyAccessor);
968      assertEquals(15, this.ownReadonlyAccessor);
969      assertFalse(Base.prototype.hasOwnProperty('ownReadonlyAccessor'));
970
971      assertThrows(() => {super.ownSetter = 35}, TypeError);
972      assertSame(undefined, super.ownSetter);
973      var descr = Object.getOwnPropertyDescriptor(this, 'ownSetter');
974      assertTrue('set' in descr);
975      assertFalse(Base.prototype.hasOwnProperty('ownSetter'));
976    },
977  };
978
979  var d = new Derived();
980  Object.defineProperty(d, 'ownReadOnly', {
981    value: 42,
982    writable: false,
983    configurable: true
984  });
985  Object.defineProperty(d, 'ownSetter', {
986    set: function() { assertUnreachable(); },
987    configurable: true
988  });
989  Object.defineProperty(d, 'ownReadonlyAccessor', {
990    get: function() { return 15; },
991    configurable: true
992  });
993
994  d.mSloppy();
995
996  var d = new Derived();
997  Object.defineProperty(d, 'ownReadOnly', {
998    value: 42,
999    writable: false,
1000    configurable: true
1001  });
1002  Object.defineProperty(d, 'ownSetter', {
1003    set: function() { assertUnreachable(); },
1004    configurable: true
1005  });
1006  Object.defineProperty(d, 'ownReadonlyAccessor', {
1007    get: function() { return 15; },
1008    configurable: true
1009  });
1010  d.mStrict();
1011}());
1012
1013
1014(function TestSetterCreatingOwnPropertiesNonConfigurable() {
1015  function Base() {}
1016  function Derived() {}
1017  Derived.prototype = {
1018    __proto__: Base.prototype,
1019    mSloppy() {
1020      assertEquals(42, this.ownReadOnly);
1021      super.ownReadOnly = 55;
1022      assertEquals(42, this.ownReadOnly);
1023      var descr = Object.getOwnPropertyDescriptor(this, 'ownReadOnly');
1024      assertEquals(42, descr.value);
1025      assertFalse(descr.configurable);
1026      assertFalse(descr.enumerable);
1027      assertFalse(descr.writable);
1028      assertFalse(Base.prototype.hasOwnProperty('ownReadOnly'));
1029
1030      assertEquals(15, this.ownReadonlyAccessor);
1031      super.ownReadonlyAccessor = 25;
1032      assertSame(undefined, super.ownReadonlyAccessor);
1033      assertEquals(15, this.ownReadonlyAccessor);
1034      var descr = Object.getOwnPropertyDescriptor(this, 'ownReadonlyAccessor');
1035      assertFalse(descr.configurable);
1036      assertFalse(descr.enumerable);
1037      assertFalse(Base.prototype.hasOwnProperty('ownReadonlyAccessor'));
1038
1039      super.ownSetter = 35;
1040      var descr = Object.getOwnPropertyDescriptor(this, 'ownSetter');
1041      assertFalse(descr.configurable);
1042      assertFalse(descr.enumerable);
1043      assertFalse(Base.prototype.hasOwnProperty('ownSetter'));
1044    },
1045    mStrict() {
1046      'use strict';
1047      var ex;
1048      assertEquals(42, this.ownReadOnly);
1049      try {
1050        super.ownReadOnly = 55;
1051      } catch (e) {
1052        ex = e;
1053      }
1054      assertInstanceof(ex, TypeError);
1055      assertEquals(
1056          "Cannot assign to read only property 'ownReadOnly' of object '#<Base>'",
1057          ex.message);
1058      assertEquals(42, this.ownReadOnly);
1059
1060      ex = null;
1061      assertEquals(15, this.ownReadonlyAccessor);
1062      try {
1063        super.ownReadonlyAccessor = 25;
1064      } catch (e) {
1065        ex = e;
1066      }
1067      assertInstanceof(ex, TypeError);
1068      assertEquals('Cannot redefine property: ownReadonlyAccessor', ex.message);
1069      assertEquals(15, this.ownReadonlyAccessor);
1070
1071      ex = null;
1072      try {
1073        super.ownSetter = 35;
1074      } catch (e) {
1075        ex = e;
1076      }
1077      assertInstanceof(ex, TypeError);
1078      assertEquals('Cannot redefine property: ownSetter', ex.message);
1079    }
1080  };
1081
1082  var d = new Derived();
1083  Object.defineProperty(d, 'ownReadOnly', { value : 42, writable : false });
1084  Object.defineProperty(d, 'ownSetter',
1085      { set : function() { assertUnreachable(); } });
1086  Object.defineProperty(d, 'ownReadonlyAccessor',
1087      { get : function() { return 15; }});
1088  d.mSloppy();
1089  d.mStrict();
1090}());
1091
1092
1093(function TestSetterInForIn() {
1094  var setCalled = 0;
1095  var getCalled = 0;
1096  function Base() {}
1097  Base.prototype = {
1098    constructor: Base,
1099    get x() {
1100      getCalled++;
1101      return 1;
1102    },
1103    set x(v) {
1104      setCalled++;
1105      this.x_.push(v);
1106    },
1107  };
1108
1109  function Derived() {
1110    this.x_ = [];
1111  }
1112  Derived.prototype = {
1113    __proto__: Base.prototype,
1114    constructor: Derived,
1115    testIter() {
1116      setCalled = 0;
1117      getCalled = 0;
1118      for (super.x in [1,2,3]) {}
1119      assertEquals(0, getCalled);
1120      assertEquals(3, setCalled);
1121      assertEquals(["0", "1", "2"], this.x_);
1122    },
1123    testIterKeyed() {
1124      setCalled = 0;
1125      getCalled = 0;
1126      for (super[x] in [1,2,3]) {}
1127      assertEquals(0, getCalled);
1128      assertEquals(3, setCalled);
1129      assertEquals(["0","1","2"], this.x_);
1130
1131      this.x_ = [];
1132      setCalled = 0;
1133      getCalled = 0;
1134      var toStringCalled = 0;
1135      var o = {toString: function () { toStringCalled++; return x }};
1136      for (super[o] in [1,2,3]) {}
1137      assertEquals(0, getCalled);
1138      assertEquals(3, setCalled);
1139      assertEquals(3, toStringCalled);
1140      assertEquals(["0","1","2"], this.x_);
1141    }
1142  };
1143
1144  new Derived().testIter();
1145
1146  var x = 'x';
1147
1148  new Derived().testIterKeyed();
1149}());
1150
1151
1152function TestKeyedSetterCreatingOwnPropertiesReconfigurable(ownReadOnly,
1153    ownReadonlyAccessor, ownSetter) {
1154  function Base() {}
1155  function Derived() {}
1156  Derived.prototype = {
1157    __proto__: Base.prototype,
1158    mSloppy() {
1159      assertEquals(42, this[ownReadOnly]);
1160      super[ownReadOnly] = 55;
1161      assertSame(undefined, super[ownReadOnly]);
1162      assertEquals(42, this[ownReadOnly]);
1163      assertFalse(Base.prototype.hasOwnProperty(ownReadOnly));
1164
1165      assertEquals(15, this[ownReadonlyAccessor]);
1166      super[ownReadonlyAccessor] = 25;
1167      assertSame(undefined, super[ownReadonlyAccessor]);
1168      assertEquals(15, this[ownReadonlyAccessor]);
1169      assertFalse(Base.prototype.hasOwnProperty(ownReadonlyAccessor));
1170
1171      super[ownSetter] = 35;
1172      assertSame(undefined, super[ownSetter]);
1173      var descr = Object.getOwnPropertyDescriptor(this, ownSetter);
1174      assertTrue('set' in descr);
1175      assertFalse(Base.prototype.hasOwnProperty(ownSetter));
1176    },
1177    mStrict() {
1178      'use strict';
1179      assertEquals(42, this[ownReadOnly]);
1180      assertThrows(() => {super[ownReadOnly] = 55}, TypeError);
1181      assertSame(undefined, super[ownReadOnly]);
1182      assertEquals(42, this[ownReadOnly]);
1183      assertFalse(Base.prototype.hasOwnProperty(ownReadOnly));
1184
1185      assertEquals(15, this[ownReadonlyAccessor]);
1186      assertThrows(() => {super[ownReadonlyAccessor] = 25}, TypeError);
1187      assertSame(undefined, super[ownReadonlyAccessor]);
1188      assertEquals(15, this[ownReadonlyAccessor]);
1189      assertFalse(Base.prototype.hasOwnProperty(ownReadonlyAccessor));
1190
1191      assertThrows(() => {super[ownSetter] = 35}, TypeError);
1192      assertSame(undefined, super[ownSetter]);
1193      var descr = Object.getOwnPropertyDescriptor(this, ownSetter);
1194      assertTrue('set' in descr);
1195      assertFalse(Base.prototype.hasOwnProperty(ownSetter));
1196    },
1197  };
1198
1199  var d = new Derived();
1200  Object.defineProperty(d, ownReadOnly, {
1201    value: 42,
1202    writable: false,
1203    configurable: true
1204  });
1205  Object.defineProperty(d, ownSetter, {
1206    set: function() { assertUnreachable(); },
1207    configurable: true
1208  });
1209  Object.defineProperty(d, ownReadonlyAccessor, {
1210    get: function() { return 15; },
1211    configurable: true
1212  });
1213
1214  d.mSloppy();
1215
1216  var d = new Derived();
1217  Object.defineProperty(d, ownReadOnly, {
1218    value: 42,
1219    writable: false,
1220    configurable: true
1221  });
1222  Object.defineProperty(d, ownSetter, {
1223    set: function() { assertUnreachable(); },
1224    configurable: true
1225  });
1226  Object.defineProperty(d, ownReadonlyAccessor, {
1227    get: function() { return 15; },
1228    configurable: true
1229  });
1230  d.mStrict();
1231}
1232TestKeyedSetterCreatingOwnPropertiesReconfigurable('ownReadOnly',
1233                                                   'ownReadonlyAccessor',
1234                                                   'ownSetter');
1235TestKeyedSetterCreatingOwnPropertiesReconfigurable(42, 43, 44);
1236
1237
1238function TestKeyedSetterCreatingOwnPropertiesNonConfigurable(
1239    ownReadOnly, ownReadonlyAccessor, ownSetter) {
1240  function Base() {}
1241  function Derived() {}
1242  Derived.prototype = {
1243    __proto__: Base.prototype,
1244    mSloppy() {
1245      assertEquals(42, this[ownReadOnly]);
1246      super[ownReadOnly] = 55;
1247      assertEquals(42, this[ownReadOnly]);
1248      var descr = Object.getOwnPropertyDescriptor(this, ownReadOnly);
1249      assertEquals(42, descr.value);
1250      assertFalse(descr.configurable);
1251      assertFalse(descr.enumerable);
1252      assertFalse(descr.writable);
1253      assertFalse(Base.prototype.hasOwnProperty(ownReadOnly));
1254
1255      assertEquals(15, this[ownReadonlyAccessor]);
1256      super[ownReadonlyAccessor] = 25;
1257      assertSame(undefined, super[ownReadonlyAccessor]);
1258      assertEquals(15, this[ownReadonlyAccessor]);
1259      var descr = Object.getOwnPropertyDescriptor(this, ownReadonlyAccessor);
1260      assertFalse(descr.configurable);
1261      assertFalse(descr.enumerable);
1262      assertFalse(Base.prototype.hasOwnProperty(ownReadonlyAccessor));
1263
1264      super[ownSetter] = 35;
1265      var descr = Object.getOwnPropertyDescriptor(this, ownSetter);
1266      assertFalse(descr.configurable);
1267      assertFalse(descr.enumerable);
1268      assertFalse(Base.prototype.hasOwnProperty(ownSetter));
1269    },
1270    mStrict() {
1271      'use strict';
1272      var ex;
1273      assertEquals(42, this[ownReadOnly]);
1274      try {
1275        super[ownReadOnly] = 55;
1276      } catch (e) {
1277        ex = e;
1278      }
1279      assertInstanceof(ex, TypeError);
1280      assertEquals(
1281          "Cannot assign to read only property '" + ownReadOnly +
1282              "' of object '#<Base>'",
1283          ex.message);
1284      assertEquals(42, this[ownReadOnly]);
1285
1286      ex = null;
1287      assertEquals(15, this[ownReadonlyAccessor]);
1288      try {
1289        super[ownReadonlyAccessor] = 25;
1290      } catch (e) {
1291        ex = e;
1292      }
1293      assertInstanceof(ex, TypeError);
1294      assertEquals('Cannot redefine property: ' + ownReadonlyAccessor,
1295                   ex.message);
1296      assertEquals(15, this[ownReadonlyAccessor]);
1297
1298      ex = null;
1299      try {
1300        super[ownSetter] = 35;
1301      } catch (e) {
1302        ex = e;
1303      }
1304      assertInstanceof(ex, TypeError);
1305      assertEquals('Cannot redefine property: ' + ownSetter, ex.message);
1306    }
1307  };
1308
1309  var d = new Derived();
1310  Object.defineProperty(d, ownReadOnly, { value : 42, writable : false });
1311  Object.defineProperty(d, ownSetter,
1312      { set : function() { assertUnreachable(); } });
1313  Object.defineProperty(d, ownReadonlyAccessor,
1314      { get : function() { return 15; }});
1315  d.mSloppy();
1316  d.mStrict();
1317}
1318TestKeyedSetterCreatingOwnPropertiesNonConfigurable('ownReadOnly',
1319    'ownReadonlyAccessor', 'ownSetter');
1320TestKeyedSetterCreatingOwnPropertiesNonConfigurable(42, 43, 44);
1321
1322
1323(function TestSetterNoProtoWalk() {
1324  function Base() {}
1325  function Derived() {}
1326  var getCalled;
1327  var setCalled;
1328  Derived.prototype = {
1329    __proto__: Base.prototype,
1330    get x() { getCalled++; return 42; },
1331    set x(v) { setCalled++; },
1332    mSloppy() {
1333      setCalled = 0;
1334      getCalled = 0;
1335      assertEquals(42, this.x);
1336      assertEquals(1, getCalled);
1337      assertEquals(0, setCalled);
1338
1339      getCalled = 0;
1340      setCalled = 0;
1341      this.x = 43;
1342      assertEquals(0, getCalled);
1343      assertEquals(1, setCalled);
1344
1345      getCalled = 0;
1346      setCalled = 0;
1347      super.x = 15;
1348      assertEquals(0, setCalled);
1349      assertEquals(0, getCalled);
1350
1351      assertEquals(15, this.x);
1352      assertEquals(0, getCalled);
1353      assertEquals(0, setCalled);
1354    },
1355    mStrict() {
1356      'use strict';
1357      setCalled = 0;
1358      getCalled = 0;
1359      assertEquals(42, this.x);
1360      assertEquals(1, getCalled);
1361      assertEquals(0, setCalled);
1362
1363      getCalled = 0;
1364      setCalled = 0;
1365      this.x = 43;
1366      assertEquals(0, getCalled);
1367      assertEquals(1, setCalled);
1368
1369      getCalled = 0;
1370      setCalled = 0;
1371      super.x = 15;
1372      assertEquals(0, setCalled);
1373      assertEquals(0, getCalled);
1374
1375      assertEquals(15, this.x);
1376      assertEquals(0, getCalled);
1377      assertEquals(0, setCalled);
1378    }
1379  };
1380
1381  new Derived().mSloppy();
1382  new Derived().mStrict();
1383}());
1384
1385
1386(function TestKeyedSetterNoProtoWalk() {
1387  var x = 'x';
1388  function Base() {}
1389  function Derived() {}
1390  var getCalled;
1391  var setCalled;
1392  Derived.prototype = {
1393    __proto__: Base.prototype,
1394    get x() { getCalled++; return 42; },
1395    set x(v) { setCalled++; },
1396    mSloppy() {
1397      setCalled = 0;
1398      getCalled = 0;
1399      assertEquals(42, this[x]);
1400      assertEquals(1, getCalled);
1401      assertEquals(0, setCalled);
1402
1403      getCalled = 0;
1404      setCalled = 0;
1405      this[x] = 43;
1406      assertEquals(0, getCalled);
1407      assertEquals(1, setCalled);
1408
1409      getCalled = 0;
1410      setCalled = 0;
1411      super[x] = 15;
1412      assertEquals(0, setCalled);
1413      assertEquals(0, getCalled);
1414
1415      assertEquals(15, this[x]);
1416      assertEquals(0, getCalled);
1417      assertEquals(0, setCalled);
1418    },
1419    mStrict() {
1420      'use strict';
1421      setCalled = 0;
1422      getCalled = 0;
1423      assertEquals(42, this[x]);
1424      assertEquals(1, getCalled);
1425      assertEquals(0, setCalled);
1426
1427      getCalled = 0;
1428      setCalled = 0;
1429      this[x] = 43;
1430      assertEquals(0, getCalled);
1431      assertEquals(1, setCalled);
1432
1433      getCalled = 0;
1434      setCalled = 0;
1435      super[x] = 15;
1436      assertEquals(0, setCalled);
1437      assertEquals(0, getCalled);
1438
1439      assertEquals(15, this[x]);
1440      assertEquals(0, getCalled);
1441      assertEquals(0, setCalled);
1442    }
1443  };
1444
1445  new Derived().mSloppy();
1446  new Derived().mStrict();
1447}());
1448
1449
1450(function TestKeyedNumericSetterNoProtoWalk() {
1451  var x = 42;
1452  function Base() {}
1453  function Derived() {}
1454  var getCalled;
1455  var setCalled;
1456  Derived.prototype = {
1457    __proto__: Base.prototype,
1458    mSloppy() {
1459      setCalled = 0;
1460      getCalled = 0;
1461      assertEquals(42, this[x]);
1462      assertEquals(1, getCalled);
1463      assertEquals(0, setCalled);
1464
1465      getCalled = 0;
1466      setCalled = 0;
1467      this[x] = 43;
1468      assertEquals(0, getCalled);
1469      assertEquals(1, setCalled);
1470
1471      getCalled = 0;
1472      setCalled = 0;
1473      super[x] = 15;
1474      assertEquals(0, setCalled);
1475      assertEquals(0, getCalled);
1476
1477      assertEquals(15, this[x]);
1478      assertEquals(0, getCalled);
1479      assertEquals(0, setCalled);
1480    },
1481    mStrict() {
1482      'use strict';
1483      setCalled = 0;
1484      getCalled = 0;
1485      assertEquals(42, this[x]);
1486      assertEquals(1, getCalled);
1487      assertEquals(0, setCalled);
1488
1489      getCalled = 0;
1490      setCalled = 0;
1491      this[x] = 43;
1492      assertEquals(0, getCalled);
1493      assertEquals(1, setCalled);
1494
1495      getCalled = 0;
1496      setCalled = 0;
1497      super[x] = 15;
1498      assertEquals(0, setCalled);
1499      assertEquals(0, getCalled);
1500
1501      assertEquals(15, this[x]);
1502      assertEquals(0, getCalled);
1503      assertEquals(0, setCalled);
1504    }
1505  };
1506
1507  Object.defineProperty(Derived.prototype, x, {
1508    get: function() { getCalled++; return 42; },
1509    set: function(v) { setCalled++; }
1510  });
1511
1512  new Derived().mSloppy();
1513  new Derived().mStrict();
1514}());
1515
1516
1517(function TestSetterDoesNotReconfigure() {
1518  function Base() {}
1519  function Derived() {}
1520  Derived.prototype = {
1521    __proto__: Derived.prototype,
1522    mStrict(){
1523      'use strict';
1524      super.nonEnumConfig = 5;
1525      var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumConfig');
1526      assertEquals(5, d1.value);
1527      assertTrue(d1.configurable);
1528      assertFalse(d1.enumerable);
1529
1530      super.nonEnumNonConfig = 5;
1531      var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumNonConfig');
1532      assertEquals(5, d1.value);
1533      assertFalse(d1.configurable);
1534      assertFalse(d1.enumerable);
1535    },
1536    mSloppy(){
1537      super.nonEnumConfig = 42;
1538      var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumConfig');
1539      assertEquals(42, d1.value);
1540      assertTrue(d1.configurable);
1541      assertFalse(d1.enumerable);
1542
1543      super.nonEnumNonConfig = 42;
1544      var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumNonConfig');
1545      assertEquals(42, d1.value);
1546      assertFalse(d1.configurable);
1547      assertFalse(d1.enumerable);
1548    }
1549  };
1550
1551  var d = new Derived();
1552  Object.defineProperty(d, 'nonEnumConfig',
1553      { value : 0, enumerable : false, configurable : true, writable : true });
1554  Object.defineProperty(d, 'nonEnumNonConfig',
1555      { value : 0, enumerable : false, configurable : false, writable : true });
1556  d.mStrict();
1557  d.mSloppy();
1558}());
1559
1560
1561(function TestKeyedSetterDoesNotReconfigure() {
1562  var nonEnumConfig = 'nonEnumConfig';
1563  var nonEnumNonConfig = 'nonEnumNonConfig';
1564  function Base() {}
1565  function Derived() {}
1566
1567  Derived.prototype = {
1568    __proto__: Base.prototype,
1569    mStrict(){
1570      'use strict';
1571      super[nonEnumConfig] = 5;
1572      var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig);
1573      assertEquals(5, d1.value);
1574      assertTrue(d1.configurable);
1575      assertFalse(d1.enumerable);
1576
1577      super[nonEnumNonConfig] = 5;
1578      var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig);
1579      assertEquals(5, d1.value);
1580      assertFalse(d1.configurable);
1581      assertFalse(d1.enumerable);
1582    },
1583    mSloppy(){
1584      super[nonEnumConfig] = 42;
1585      var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig);
1586      assertEquals(42, d1.value);
1587      assertTrue(d1.configurable);
1588      assertFalse(d1.enumerable);
1589
1590      super[nonEnumNonConfig] = 42;
1591      var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig);
1592      assertEquals(42, d1.value);
1593      assertFalse(d1.configurable);
1594      assertFalse(d1.enumerable);
1595    }
1596  };
1597
1598  var d = new Derived();
1599  Object.defineProperty(d, nonEnumConfig,
1600      { value : 0, enumerable : false, configurable : true, writable : true });
1601  Object.defineProperty(d, nonEnumNonConfig,
1602      { value : 0, enumerable : false, configurable : false, writable : true });
1603  d.mStrict();
1604  d.mSloppy();
1605}());
1606
1607
1608(function TestKeyedNumericSetterDoesNotReconfigure() {
1609  var nonEnumConfig = 42;
1610  var nonEnumNonConfig = 43;
1611  function Base() {}
1612  function Derived() {}
1613
1614  Derived.prototype = {
1615    __proto__: Base.prototype,
1616    mStrict(){
1617      'use strict';
1618      super[nonEnumConfig] = 5;
1619      var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig);
1620      assertEquals(5, d1.value);
1621      assertTrue(d1.configurable);
1622      assertFalse(d1.enumerable);
1623
1624      super[nonEnumNonConfig] = 5;
1625      var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig);
1626      assertEquals(5, d1.value);
1627      assertFalse(d1.configurable);
1628      assertFalse(d1.enumerable);
1629    },
1630    mSloppy(){
1631      super[nonEnumConfig] = 42;
1632      var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig);
1633      assertEquals(42, d1.value);
1634      assertTrue(d1.configurable);
1635      assertFalse(d1.enumerable);
1636
1637      super[nonEnumNonConfig] = 42;
1638      var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig);
1639      assertEquals(42, d1.value);
1640      assertFalse(d1.configurable);
1641      assertFalse(d1.enumerable);
1642    }
1643  };
1644
1645  var d = new Derived();
1646  Object.defineProperty(d, nonEnumConfig,
1647      { value : 0, enumerable : false, configurable : true, writable : true });
1648  Object.defineProperty(d, nonEnumNonConfig,
1649      { value : 0, enumerable : false, configurable : false, writable : true });
1650  d.mStrict();
1651  d.mSloppy();
1652}());
1653
1654
1655(function TestCountOperations() {
1656  function Base() {}
1657  Base.prototype = {
1658    constructor: Base,
1659    get x() {
1660      return this._x;
1661    },
1662    set x(v) {
1663      this._x = v;
1664    },
1665    _x: 1
1666  };
1667
1668  function Derived() {}
1669  Derived.__proto__ = Base;
1670  Derived.prototype = {
1671    __proto__: Base.prototype,
1672    constructor: Derived,
1673    _x: 2,
1674    testCounts() {
1675      assertEquals(2, this._x);
1676      assertEquals(2, super.x);
1677      super.x++;
1678      assertEquals(3, super.x);
1679      ++super.x;
1680      assertEquals(4, super.x);
1681      assertEquals(4, super.x++);
1682      assertEquals(5, super.x);
1683      assertEquals(6, ++super.x);
1684      assertEquals(6, super.x);
1685      assertEquals(6, this._x);
1686
1687      super.x--;
1688      assertEquals(5, super.x);
1689      --super.x;
1690      assertEquals(4, super.x);
1691      assertEquals(4, super.x--);
1692      assertEquals(3, super.x);
1693      assertEquals(2, --super.x);
1694      assertEquals(2, super.x);
1695      assertEquals(2, this._x);
1696    }
1697  };
1698  new Derived().testCounts();
1699}());
1700
1701
1702(function TestKeyedCountOperations() {
1703  var x = 'x';
1704  function Base() {}
1705  Base.prototype = {
1706    constructor: Base,
1707    get x() {
1708      return this._x;
1709    },
1710    set x(v) {
1711      this._x = v;
1712    },
1713    _x: 1
1714  };
1715
1716  function Derived() {}
1717  Derived.__proto__ = Base;
1718  Derived.prototype = {
1719    __proto__: Base.prototype,
1720    constructor: Derived,
1721    _x: 2,
1722    testCounts() {
1723      assertEquals(2, this._x);
1724      assertEquals(2, super[x]);
1725      super[x]++;
1726      assertEquals(3, super[x]);
1727      ++super[x];
1728      assertEquals(4, super[x]);
1729      assertEquals(4, super[x]++);
1730      assertEquals(5, super[x]);
1731      assertEquals(6, ++super[x]);
1732      assertEquals(6, super[x]);
1733      assertEquals(6, this._x);
1734
1735      super[x]--;
1736      assertEquals(5, super[x]);
1737      --super[x];
1738      assertEquals(4, super[x]);
1739      assertEquals(4, super[x]--);
1740      assertEquals(3, super[x]);
1741      assertEquals(2, --super[x]);
1742      assertEquals(2, super[x]);
1743      assertEquals(2, this._x);
1744    }
1745  };
1746  new Derived().testCounts();
1747}());
1748
1749
1750(function TestKeyedNumericCountOperations() {
1751  var x = 42;
1752  function Base() {}
1753  Base.prototype = {
1754    constructor: Base,
1755    _x: 1
1756  };
1757
1758  Object.defineProperty(Base.prototype, x, {
1759    get: function() { return this._x; },
1760    set: function(v) { this._x = v;; }
1761  });
1762
1763  function Derived() {}
1764  Derived.__proto__ = Base;
1765  Derived.prototype = {
1766    __proto__: Base.prototype,
1767    constructor: Derived,
1768    _x: 2,
1769    testCounts() {
1770      assertEquals(2, this._x);
1771      assertEquals(2, super[x]);
1772      super[x]++;
1773      assertEquals(3, super[x]);
1774      ++super[x];
1775      assertEquals(4, super[x]);
1776      assertEquals(4, super[x]++);
1777      assertEquals(5, super[x]);
1778      assertEquals(6, ++super[x]);
1779      assertEquals(6, super[x]);
1780      assertEquals(6, this._x);
1781
1782      super[x]--;
1783      assertEquals(5, super[x]);
1784      --super[x];
1785      assertEquals(4, super[x]);
1786      assertEquals(4, super[x]--);
1787      assertEquals(3, super[x]);
1788      assertEquals(2, --super[x]);
1789      assertEquals(2, super[x]);
1790      assertEquals(2, this._x);
1791    }
1792  };
1793  new Derived().testCounts();
1794}());
1795
1796
1797(function TestSetterSuperNonWritable() {
1798  function Base() {}
1799  Object.defineProperty(Base.prototype, 'x', { value : 27, writable: false });
1800  function Derived() {}
1801  Derived.prototype = {
1802    __proto__: Base.prototype,
1803    constructor: Derived,
1804    mSloppy() {
1805      assertEquals(27, super.x);
1806      assertEquals(27, this.x);
1807      super.x = 10;
1808      assertEquals(27, super.x);
1809      assertEquals(27, this.x);
1810    },
1811    mStrict() {
1812      'use strict';
1813      assertEquals(27, super.x);
1814      assertEquals(27, this.x);
1815      var ex = null;
1816      try { super.x = 10; } catch(e) { ex = e; }
1817      assertInstanceof(ex, TypeError);
1818      assertEquals(27, super.x);
1819      assertEquals(27, this.x);
1820    }
1821  };
1822  new Derived().mSloppy();
1823  new Derived().mStrict();
1824}());
1825
1826
1827(function TestSetterKeyedSuperNonWritable() {
1828  var x = 'xyz';
1829  function Base() {}
1830  Object.defineProperty(Base.prototype, x, { value : 27, writable: false });
1831  function Derived() {}
1832
1833  Derived.prototype = {
1834    __proto__: Base.prototype,
1835    constructor: Derived,
1836    mSloppy() {
1837      assertEquals(27, super[x]);
1838      assertEquals(27, this[x]);
1839      super[x] = 10;
1840      assertEquals(27, super[x]);
1841      assertEquals(27, this[x]);
1842    },
1843    mStrict() {
1844      'use strict';
1845      assertEquals(27, super[x]);
1846      assertEquals(27, this[x]);
1847      var ex = null;
1848      try { super[x] = 10; } catch(e) { ex = e; }
1849      assertInstanceof(ex, TypeError);
1850      assertEquals(27, super[x]);
1851      assertEquals(27, this[x]);
1852    }
1853  };
1854  new Derived().mSloppy();
1855  new Derived().mStrict();
1856}());
1857
1858
1859(function TestSetterKeyedNumericSuperNonWritable() {
1860  var x = 42;
1861  function Base() {}
1862  Object.defineProperty(Base.prototype, x, { value : 27, writable: false });
1863  function Derived() {}
1864
1865  Derived.prototype = {
1866    __proto__: Base.prototype,
1867    constructor: Derived,
1868    mSloppy() {
1869      assertEquals(27, super[x]);
1870      assertEquals(27, this[x]);
1871      super[x] = 10;
1872      assertEquals(27, super[x]);
1873      assertEquals(27, this[x]);
1874    },
1875    mStrict() {
1876      'use strict';
1877      assertEquals(27, super[x]);
1878      assertEquals(27, this[x]);
1879      var ex = null;
1880      try { super[x] = 10; } catch(e) { ex = e; }
1881      assertInstanceof(ex, TypeError);
1882      assertEquals(27, super[x]);
1883      assertEquals(27, this[x]);
1884    }
1885  };
1886  new Derived().mSloppy();
1887  new Derived().mStrict();
1888}());
1889
1890
1891(function TestSuperCall() {
1892  'use strict';
1893
1894  var baseCalled = 0;
1895  var derivedCalled = 0;
1896  var derivedDerivedCalled = 0;
1897
1898  class Base {
1899    constructor() {
1900      baseCalled++;
1901    }
1902  }
1903
1904  class Derived extends Base {
1905    constructor() {
1906      let r = super();
1907      assertEquals(this, r);
1908      derivedCalled++;
1909    }
1910  }
1911
1912  assertEquals(Base, Base.prototype.constructor);
1913  assertEquals(Base.prototype, Derived.prototype.__proto__);
1914
1915  baseCalled = 0;
1916  derivedCalled = 0;
1917  new Derived();
1918  assertEquals(1, baseCalled);
1919  assertEquals(1, derivedCalled);
1920
1921  class DerivedDerived extends Derived {
1922    constructor() {
1923      let r = super();
1924      assertEquals(this, r);
1925      derivedDerivedCalled++;
1926    }
1927  }
1928
1929  baseCalled = 0;
1930  derivedCalled = 0;
1931  derivedDerivedCalled = 0;
1932  new DerivedDerived();
1933  assertEquals(1, baseCalled);
1934  assertEquals(1, derivedCalled);
1935  assertEquals(1, derivedDerivedCalled);
1936
1937  class Base2 {
1938    constructor(v) {
1939      this.fromBase = v;
1940    }
1941  }
1942  class Derived2 extends Base2 {
1943    constructor(v1, v2) {
1944      let r = super(v1);
1945      assertEquals(this, r);
1946      this.fromDerived = v2;
1947    }
1948  }
1949
1950  var d = new Derived2("base", "derived");
1951  assertEquals("base", d.fromBase);
1952  assertEquals("derived", d.fromDerived);
1953
1954  var calls = 0;
1955  class G {
1956    constructor() {
1957      calls++;
1958    }
1959  }
1960
1961  class F extends Object {
1962    constructor() {
1963      super();
1964    }
1965  }
1966  F.__proto__ = G;
1967  new F();
1968  assertEquals(1, calls);
1969  F.__proto__ = function() {};
1970  new F();
1971  assertEquals(1, calls);
1972}());
1973
1974
1975(function TestExtendsObject() {
1976  'use strict';
1977  class F extends Object { }
1978  var f = new F(42);
1979
1980  assertInstanceof(f, F);
1981  assertInstanceof(f, Object);
1982}());
1983
1984
1985(function TestSuperCallErrorCases() {
1986  'use strict';
1987  class T extends Object {
1988    constructor() {
1989      super();
1990    }
1991  }
1992
1993  T.__proto__ = null;
1994  assertThrows(function() { new T(); }, TypeError);
1995}());
1996
1997
1998(function TestSuperPropertyInEval() {
1999  'use strict';
2000  let y = 3;
2001  class Base {
2002    m() { return 1; }
2003    get x() { return 2; }
2004  }
2005  class Derived extends Base {
2006    evalM() {
2007      assertEquals(1, eval('super.m()'));
2008    }
2009    evalX() {
2010      assertEquals(2, eval('super.x'));
2011    }
2012    globalEval1() {
2013      assertThrows('super.x', SyntaxError);
2014      assertThrows('super.m()', SyntaxError);
2015    }
2016    globalEval2() {
2017      super.x;
2018      assertThrows('super.x', SyntaxError);
2019      assertThrows('super.m()', SyntaxError);
2020    }
2021  }
2022  let d = new Derived();
2023  d.globalEval1();
2024  d.globalEval2();
2025  d.evalM();
2026  d.evalX();
2027})();
2028
2029
2030(function TestSuperPropertyInArrow() {
2031  'use strict';
2032  let y = 3;
2033  class Base {
2034    m() { return 1; }
2035    get x() { return 2; }
2036  }
2037  class Derived extends Base {
2038    arrow() {
2039      assertSame(super.x, (() => super.x)());
2040      assertSame(super.m(), (() => super.m())());
2041      return (() => super.m())();
2042    }
2043  }
2044  let d = new Derived();
2045  assertSame(1, d.arrow());
2046})();
2047
2048
2049(function TestSuperInOtherScopes() {
2050  var p = {x: 99};
2051  var o0 = {__proto__: p, f() { return eval("'use strict'; super.x") }};
2052  assertEquals(p.x, o0.f());
2053  var o1 = {__proto__: p, f() { with ({}) return super.x }};
2054  assertEquals(p.x, o1.f());
2055  var o2 = {__proto__: p, f({a}) { return super.x }};
2056  assertEquals(p.x, o2.f({}));
2057  var o3 = {__proto__: p, f(...a) { return super.x }};
2058  assertEquals(p.x, o3.f());
2059  var o4 = {__proto__: p, f() { 'use strict'; { let x; return super.x } }};
2060  assertEquals(p.x, o4.f());
2061})();
2062
2063
2064(function TestSuperCallInOtherScopes() {
2065  class C {constructor() { this.x = 99 }}
2066  class D0 extends C {constructor() { eval("'use strict'; super()") }}
2067  assertEquals(99, (new D0).x);
2068  class D2 extends C {constructor({a}) { super() }}
2069  assertEquals(99, (new D2({})).x);
2070  class D3 extends C {constructor(...a) { super() }}
2071  assertEquals(99, (new D3()).x);
2072  class D4 extends C {constructor() { { let x; super() } }}
2073  assertEquals(99, (new D4).x);
2074})();
2075
2076
2077(function TestSuperCallInEval() {
2078  'use strict';
2079  class Base {
2080    constructor(x) {
2081      this.x = x;
2082    }
2083  }
2084  class Derived extends Base {
2085    constructor(x) {
2086      let r = eval('super(x)');
2087      assertEquals(this, r);
2088    }
2089  }
2090  let d = new Derived(42);
2091  assertSame(42, d.x);
2092})();
2093
2094
2095(function TestSuperCallInArrow() {
2096  'use strict';
2097  class Base {
2098    constructor(x) {
2099      this.x = x;
2100    }
2101  }
2102  class Derived extends Base {
2103    constructor(x) {
2104      let r = (() => super(x))();
2105      assertEquals(this, r);
2106    }
2107  }
2108  let d = new Derived(42);
2109  assertSame(42, d.x);
2110})();
2111
2112
2113(function TestSuperCallEscapes() {
2114  'use strict';
2115  class Base {
2116    constructor(x) {
2117      this.x = x;
2118    }
2119  }
2120
2121  let f;
2122  class Derived extends Base {
2123    constructor() {
2124      f = () => super(2);
2125    }
2126  }
2127  assertThrows(function() {
2128    new Derived();
2129  }, ReferenceError);
2130
2131  let o = f();
2132  assertEquals(2, o.x);
2133  assertInstanceof(o, Derived);
2134
2135  assertThrows(function() {
2136    f();
2137  }, ReferenceError);
2138})();
2139
2140
2141(function TestSuperCallInLoop() {
2142  'use strict';
2143  class Base {
2144    constructor(x) {
2145      this.x = x;
2146    }
2147  }
2148  class Derived extends Base {
2149    constructor(x, n) {
2150      for (var i = 0; i < n; ++i) {
2151        super(x);
2152      }
2153    }
2154  }
2155
2156  let o = new Derived(23, 1);
2157  assertEquals(23, o.x);
2158  assertInstanceof(o, Derived);
2159
2160  assertThrows("new Derived(42, 0)", ReferenceError);
2161  assertThrows("new Derived(65, 2)", ReferenceError);
2162})();
2163
2164
2165(function TestSuperCallReentrant() {
2166  'use strict';
2167  class Base {
2168    constructor(fun) {
2169      this.x = fun();
2170    }
2171  }
2172  class Derived extends Base {
2173    constructor(x) {
2174      let f = () => super(() => x)
2175      super(f);
2176    }
2177  }
2178  assertThrows("new Derived(23)", ReferenceError);
2179})();
2180
2181
2182(function TestSuperCallSpreadInEval() {
2183  'use strict';
2184  class Base {
2185    constructor(x) {
2186      this.x = x;
2187    }
2188  }
2189  class Derived extends Base {
2190    constructor(x) {
2191      let r = eval('super(...[x])');
2192      assertEquals(this, r);
2193    }
2194  }
2195  let d = new Derived(42);
2196  assertSame(42, d.x);
2197})();
2198
2199
2200(function TestSuperCallSpreadInArrow() {
2201  'use strict';
2202  class Base {
2203    constructor(x) {
2204      this.x = x;
2205    }
2206  }
2207  class Derived extends Base {
2208    constructor(x) {
2209      let r = (() => super(...[x]))();
2210      assertEquals(this, r);
2211    }
2212  }
2213  let d = new Derived(42);
2214  assertSame(42, d.x);
2215})();
2216