1// Copyright 2015 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 --harmony-reflect --harmony-regexp-subclass
6// Flags: --expose-gc --strong-mode
7
8"use strict";
9
10
11function checkPrototypeChain(object, constructors) {
12  var proto = object.__proto__;
13  for (var i = 0; i < constructors.length; i++) {
14    assertEquals(constructors[i].prototype, proto);
15    assertEquals(constructors[i], proto.constructor);
16    proto = proto.__proto__;
17  }
18}
19
20
21(function() {
22  class A extends Object {
23    constructor(...args) {
24      assertFalse(new.target === undefined);
25      super(...args);
26      this.a = 42;
27      this.d = 4.2;
28      this.o = {foo:153};
29    }
30  }
31
32  var s = new A("foo");
33  assertTrue(s instanceof Object);
34  assertTrue(s instanceof A);
35  assertEquals("object", typeof s);
36  checkPrototypeChain(s, [A, Object]);
37  assertEquals(42, s.a);
38  assertEquals(4.2, s.d);
39  assertEquals(153, s.o.foo);
40
41  var s1 = new A("bar");
42  assertTrue(%HaveSameMap(s, s1));
43
44
45  var n = new A(153);
46  assertTrue(n instanceof Object);
47  assertTrue(n instanceof A);
48  assertEquals("object", typeof s);
49  checkPrototypeChain(s, [A, Object]);
50  assertEquals(42, n.a);
51  assertEquals(4.2, n.d);
52  assertEquals(153, n.o.foo);
53
54  var n1 = new A(312);
55  assertTrue(%HaveSameMap(n, n1));
56  assertTrue(%HaveSameMap(n, s));
57
58
59  var b = new A(true);
60  assertTrue(b instanceof Object);
61  assertTrue(b instanceof A);
62  assertEquals("object", typeof s);
63  checkPrototypeChain(s, [A, Object]);
64  assertEquals(42, b.a);
65  assertEquals(4.2, b.d);
66  assertEquals(153, b.o.foo);
67
68  var b1 = new A(true);
69  assertTrue(%HaveSameMap(b, b1));
70  assertTrue(%HaveSameMap(b, s));
71
72  gc();
73})();
74
75
76(function() {
77  class A extends Function {
78    constructor(...args) {
79      assertFalse(new.target === undefined);
80      super(...args);
81      // Strong functions are not extensible, so don't add fields.
82      if (args[args.length - 1].indexOf("use strong") >= 0) {
83        assertThrows(()=>{ this.a = 10; }, TypeError);
84        return;
85      }
86      this.a = 42;
87      this.d = 4.2;
88      this.o = {foo:153};
89    }
90  }
91  var sloppy_func = new A("");
92  var strict_func = new A("'use strict';");
93  assertNull(sloppy_func.caller);
94  assertThrows("strict_f.caller");
95  assertNull(Object.getOwnPropertyDescriptor(sloppy_func, "caller").value);
96  assertEquals(undefined, Object.getOwnPropertyDescriptor(strict_func, "caller"));
97
98  function CheckFunction(func, is_strong) {
99    assertEquals("function", typeof func);
100    assertTrue(func instanceof Object);
101    assertTrue(func instanceof Function);
102    assertTrue(func instanceof A);
103    checkPrototypeChain(func, [A, Function, Object]);
104    if (!is_strong) {
105      assertEquals(42, func.a);
106      assertEquals(4.2, func.d);
107      assertEquals(153, func.o.foo);
108      assertTrue(undefined !== func.prototype);
109      func.prototype.bar = "func.bar";
110      var obj = new func();
111      assertTrue(obj instanceof Object);
112      assertTrue(obj instanceof func);
113      assertEquals("object", typeof obj);
114      assertEquals(113, obj.foo);
115      assertEquals("func.bar", obj.bar);
116      delete func.prototype.bar;
117    }
118  }
119
120  var source = "this.foo = 113;";
121
122  // Sloppy function
123  var sloppy_func = new A(source);
124  assertTrue(undefined !== sloppy_func.prototype);
125  CheckFunction(sloppy_func, false);
126
127  var sloppy_func1 = new A("return 312;");
128  assertTrue(%HaveSameMap(sloppy_func, sloppy_func1));
129
130  // Strict function
131  var strict_func = new A("'use strict'; " + source);
132  assertFalse(%HaveSameMap(strict_func, sloppy_func));
133  CheckFunction(strict_func, false);
134
135  var strict_func1 = new A("'use strict'; return 312;");
136  assertTrue(%HaveSameMap(strict_func, strict_func1));
137
138  // Strong function
139  var strong_func = new A("'use strong'; " + source);
140  assertFalse(%HaveSameMap(strong_func, sloppy_func));
141  assertFalse(%HaveSameMap(strong_func, strict_func));
142  CheckFunction(strong_func, true);
143
144  var strong_func1 = new A("'use strong'; return 312;");
145  assertTrue(%HaveSameMap(strong_func, strong_func1));
146
147  gc();
148})();
149
150
151(function() {
152  class A extends Boolean {
153    constructor(...args) {
154      assertFalse(new.target === undefined);
155      super(...args);
156      this.a = 42;
157      this.d = 4.2;
158      this.o = {foo:153};
159    }
160  }
161
162  var o = new A(true);
163  assertTrue(o instanceof Object);
164  assertTrue(o instanceof Boolean);
165  assertTrue(o instanceof A);
166  assertEquals("object", typeof o);
167  checkPrototypeChain(o, [A, Boolean]);
168  assertTrue(o.valueOf());
169  assertEquals(42, o.a);
170  assertEquals(4.2, o.d);
171  assertEquals(153, o.o.foo);
172
173  var o1 = new A(false);
174  assertTrue(%HaveSameMap(o, o1));
175
176  gc();
177})();
178
179
180function TestErrorSubclassing(error) {
181  class A extends error {
182    constructor(...args) {
183      assertFalse(new.target === undefined);
184      super(...args);
185      this.a = 42;
186      this.d = 4.2;
187      this.o = {foo:153};
188    }
189  }
190
191  var o = new A("message");
192  assertTrue(o instanceof Object);
193  assertTrue(o instanceof error);
194  assertTrue(o instanceof Error);
195  assertTrue(o instanceof A);
196  assertEquals("object", typeof o);
197  if (error == Error) {
198    checkPrototypeChain(o, [A, Error, Object]);
199  } else {
200    checkPrototypeChain(o, [A, error, Error, Object]);
201  }
202  assertEquals("message", o.message);
203  assertEquals(error.name + ": message", o.toString());
204  assertEquals(42, o.a);
205  assertEquals(4.2, o.d);
206  assertEquals(153, o.o.foo);
207
208  var o1 = new A("achtung!");
209  assertTrue(%HaveSameMap(o, o1));
210
211  gc();
212}
213
214
215(function() {
216  TestErrorSubclassing(Error);
217  TestErrorSubclassing(EvalError);
218  TestErrorSubclassing(RangeError);
219  TestErrorSubclassing(ReferenceError);
220  TestErrorSubclassing(SyntaxError);
221  TestErrorSubclassing(TypeError);
222  TestErrorSubclassing(URIError);
223})();
224
225
226(function() {
227  class A extends Number {
228    constructor(...args) {
229      assertFalse(new.target === undefined);
230      super(...args);
231      this.a = 42;
232      this.d = 4.2;
233      this.o = {foo:153};
234    }
235  }
236
237  var o = new A(153);
238  assertTrue(o instanceof Object);
239  assertTrue(o instanceof Number);
240  assertTrue(o instanceof A);
241  assertEquals("object", typeof o);
242  checkPrototypeChain(o, [A, Number, Object]);
243  assertEquals(153, o.valueOf());
244  assertEquals(42, o.a);
245  assertEquals(4.2, o.d);
246  assertEquals(153, o.o.foo);
247
248  var o1 = new A(312);
249  assertTrue(%HaveSameMap(o, o1));
250
251  gc();
252})();
253
254
255(function() {
256  class A extends Date {
257    constructor(...args) {
258      assertFalse(new.target === undefined);
259      super(...args);
260      this.a = 42;
261      this.d = 4.2;
262      this.o = {foo:153};
263    }
264  }
265
266  var o = new A(1234567890);
267  assertTrue(o instanceof Object);
268  assertTrue(o instanceof Date);
269  assertTrue(o instanceof A);
270  assertEquals("object", typeof o);
271  checkPrototypeChain(o, [A, Date, Object]);
272  assertEquals(1234567890, o.getTime());
273  assertEquals(42, o.a);
274  assertEquals(4.2, o.d);
275  assertEquals(153, o.o.foo);
276
277  var o1 = new A(2015, 10, 29);
278  assertEquals(2015, o1.getFullYear());
279  assertEquals(10, o1.getMonth());
280  assertEquals(29, o1.getDate());
281  assertTrue(%HaveSameMap(o, o1));
282
283  gc();
284})();
285
286
287(function() {
288  class A extends String {
289    constructor(...args) {
290      assertFalse(new.target === undefined);
291      super(...args);
292      this.a = 42;
293      this.d = 4.2;
294      this.o = {foo:153};
295    }
296  }
297
298  var o = new A("foo");
299  assertTrue(o instanceof Object);
300  assertTrue(o instanceof String);
301  assertTrue(o instanceof A);
302  assertEquals("object", typeof o);
303  checkPrototypeChain(o, [A, String, Object]);
304
305  assertEquals("foo", o.valueOf());
306  assertEquals(42, o.a);
307  assertEquals(4.2, o.d);
308  assertEquals(153, o.o.foo);
309
310  var o1 = new A("bar");
311  assertTrue(%HaveSameMap(o, o1));
312
313  gc();
314})();
315
316
317(function() {
318  class A extends RegExp {
319    constructor(...args) {
320      assertFalse(new.target === undefined);
321      super(...args);
322      this.a = 42;
323      this.d = 4.2;
324      this.o = {foo:153};
325    }
326  }
327
328  var o = new A("o(..)h", "g");
329  assertTrue(o instanceof Object);
330  assertTrue(o instanceof RegExp);
331  assertTrue(o instanceof A);
332  assertEquals("object", typeof o);
333  checkPrototypeChain(o, [A, RegExp, Object]);
334  assertTrue(o.test("ouch"));
335  assertArrayEquals(["ouch", "uc"], o.exec("boom! ouch! bam!"));
336  assertEquals("o(..)h", o.source);
337  assertTrue(o.global);
338  assertFalse(o.ignoreCase);
339  assertFalse(o.multiline);
340  assertEquals(10, o.lastIndex);
341  assertEquals(42, o.a);
342  assertEquals(4.2, o.d);
343  assertEquals(153, o.o.foo);
344
345  var o1 = new A(7);
346  assertTrue(%HaveSameMap(o, o1));
347
348  gc();
349})();
350
351
352(function TestArraySubclassing() {
353  class A extends Array {
354    constructor(...args) {
355      assertFalse(new.target === undefined);
356      super(...args);
357      this.a = 42;
358      this.d = 4.2;
359      this.o = {foo:153};
360    }
361  }
362
363  var o = new Array(13);
364  assertTrue(o instanceof Object);
365  assertTrue(o instanceof Array);
366  assertEquals("object", typeof o);
367  checkPrototypeChain(o, [Array, Object]);
368  assertEquals(13, o.length);
369
370  var o = new A(10);
371  assertTrue(o instanceof Object);
372  assertTrue(o instanceof Array);
373  assertTrue(o instanceof A);
374  assertEquals("object", typeof o);
375  checkPrototypeChain(o, [A, Array, Object]);
376  assertEquals(10, o.length);
377  assertEquals(42, o.a);
378  assertEquals(4.2, o.d);
379  assertEquals(153, o.o.foo);
380
381  var o1 = new A(7);
382  assertTrue(%HaveSameMap(o, o1));
383})();
384
385
386var TypedArray = Uint8Array.__proto__;
387
388function TestTypedArraySubclassing(array) {
389  class A extends array {
390    constructor(...args) {
391      assertFalse(new.target === undefined);
392      super(...args);
393      this.a = 42;
394      this.d = 4.2;
395      this.o = {foo:153};
396    }
397  }
398
399  var o = new array(13);
400  assertTrue(o instanceof Object);
401  assertTrue(o instanceof TypedArray);
402  assertTrue(o instanceof array);
403  assertEquals("object", typeof o);
404  checkPrototypeChain(o, [array, TypedArray, Object]);
405  assertEquals(13, o.length);
406
407  var o = new A(10);
408  assertTrue(o instanceof Object);
409  assertTrue(o instanceof TypedArray);
410  assertTrue(o instanceof array);
411  assertTrue(o instanceof A);
412  assertEquals("object", typeof o);
413  checkPrototypeChain(o, [A, array, TypedArray, Object]);
414  assertEquals(10, o.length);
415  assertEquals(42, o.a);
416  assertEquals(4.2, o.d);
417  assertEquals(153, o.o.foo);
418
419  var o1 = new A(7);
420  assertTrue(%HaveSameMap(o, o1));
421}
422
423
424(function() {
425  TestTypedArraySubclassing(Int8Array);
426  TestTypedArraySubclassing(Uint8Array);
427  TestTypedArraySubclassing(Uint8ClampedArray);
428  TestTypedArraySubclassing(Int16Array);
429  TestTypedArraySubclassing(Uint16Array);
430  TestTypedArraySubclassing(Int32Array);
431  TestTypedArraySubclassing(Uint32Array);
432  TestTypedArraySubclassing(Float32Array);
433  TestTypedArraySubclassing(Float64Array);
434})();
435
436
437function TestMapSetSubclassing(container, is_map) {
438  var keys = [{name: "banana"}, {name: "cow"}, {name: "orange"}, {name: "chicken"}, {name: "apple"}];
439
440  class A extends container {
441    constructor(...args) {
442      assertFalse(new.target === undefined);
443      super(...args);
444      this.a = 42;
445      this.d = 4.2;
446      this.o = {foo:153};
447    }
448  }
449
450  var o = new A();
451  assertTrue(o instanceof Object);
452  assertTrue(o instanceof container);
453  assertTrue(o instanceof A);
454  assertEquals("object", typeof o);
455  checkPrototypeChain(o, [A, container, Object]);
456
457  for (var i = 0; i < keys.length; i++) {
458    if (is_map) {
459      o.set(keys[i], (i + 1) * 11);
460    } else {
461      o.add(keys[i]);
462    }
463  }
464  o.delete(keys[1]);
465  o.delete(keys[3]);
466
467  assertTrue(o.has(keys[0]));
468  assertFalse(o.has(keys[1]));
469  assertTrue(o.has(keys[2]));
470  assertFalse(o.has(keys[1]));
471  assertTrue(o.has(keys[4]));
472  if (is_map) {
473    assertEquals(11, o.get(keys[0]));
474    assertEquals(undefined, o.get(keys[1]));
475    assertEquals(33, o.get(keys[2]));
476    assertEquals(undefined, o.get(keys[3]));
477    assertEquals(55, o.get(keys[4]));
478  }
479  assertEquals(42, o.a);
480  assertEquals(4.2, o.d);
481  assertEquals(153, o.o.foo);
482
483  var o1 = new A();
484  assertTrue(%HaveSameMap(o, o1));
485
486  gc();
487}
488
489
490(function() {
491  TestMapSetSubclassing(Map, true);
492  TestMapSetSubclassing(WeakMap, true);
493  TestMapSetSubclassing(Set, false);
494  TestMapSetSubclassing(WeakSet, false);
495})();
496
497
498(function() {
499  class A extends ArrayBuffer {
500    constructor(...args) {
501      assertFalse(new.target === undefined);
502      super(...args);
503      this.a = 42;
504      this.d = 4.2;
505      this.o = {foo:153};
506    }
507  }
508
509  var o = new A(16);
510  assertTrue(o instanceof Object);
511  assertTrue(o instanceof ArrayBuffer);
512  assertTrue(o instanceof A);
513  assertEquals("object", typeof o);
514  checkPrototypeChain(o, [A, ArrayBuffer, Object]);
515
516  assertEquals(16, o.byteLength);
517  assertEquals(42, o.a);
518  assertEquals(4.2, o.d);
519  assertEquals(153, o.o.foo);
520
521  var o1 = new A("bar");
522  assertTrue(%HaveSameMap(o, o1));
523
524
525  class MyInt32Array extends Int32Array {
526    constructor(v, name) {
527      super(v);
528      this.name = name;
529    }
530  }
531
532  class MyUint32Array extends Uint32Array {
533    constructor(v, name) {
534      super(v);
535      this.name = name;
536    }
537  }
538
539  var int32view = new MyInt32Array(o, "cats");
540  var uint32view = new MyUint32Array(o, "dogs");
541
542  int32view[0] = -2;
543  uint32view[1] = 0xffffffff;
544
545  assertEquals("cats", int32view.name);
546  assertEquals("dogs", uint32view.name);
547  assertEquals(-2, int32view[0]);
548  assertEquals(-1, int32view[1]);
549  assertEquals(0xfffffffe, uint32view[0]);
550  assertEquals(0xffffffff, uint32view[1]);
551
552  gc();
553})();
554
555
556(function() {
557  class A extends DataView {
558    constructor(...args) {
559      assertFalse(new.target === undefined);
560      super(...args);
561      this.a = 42;
562      this.d = 4.2;
563      this.o = {foo:153};
564    }
565  }
566
567  var buffer = new ArrayBuffer(16);
568  var o = new A(buffer);
569  assertTrue(o instanceof Object);
570  assertTrue(o instanceof DataView);
571  assertTrue(o instanceof A);
572  assertEquals("object", typeof o);
573  checkPrototypeChain(o, [A, DataView, Object]);
574
575  o.setUint32(0, 0xcafebabe, false);
576  assertEquals(0xcafebabe, o.getUint32(0, false));
577  assertEquals(0xbebafeca, o.getUint32(0, true));
578  assertEquals(42, o.a);
579  assertEquals(4.2, o.d);
580  assertEquals(153, o.o.foo);
581
582  var o1 = new A(buffer);
583  assertTrue(%HaveSameMap(o, o1));
584
585  gc();
586})();
587
588
589(function() {
590  var GeneratorFunction = (function*() {}).constructor;
591  class A extends GeneratorFunction {
592    constructor(...args) {
593      assertFalse(new.target === undefined);
594      super(...args);
595      // Strong functions are not extensible, so don't add fields.
596      if (args[args.length - 1].indexOf("use strong") >= 0) {
597        assertThrows(()=>{ this.a = 10; }, TypeError);
598        return;
599      }
600      this.a = 42;
601      this.d = 4.2;
602      this.o = {foo:153};
603    }
604  }
605  var sloppy_func = new A("yield 153;");
606  var strict_func = new A("'use strict'; yield 153;");
607  // Unfortunately the difference is not observable from outside.
608  assertThrows("sloppy_func.caller");
609  assertThrows("strict_f.caller");
610  assertEquals(undefined, Object.getOwnPropertyDescriptor(sloppy_func, "caller"));
611  assertEquals(undefined, Object.getOwnPropertyDescriptor(strict_func, "caller"));
612
613  function CheckFunction(func, is_strong) {
614    assertEquals("function", typeof func);
615    assertTrue(func instanceof Object);
616    assertTrue(func instanceof Function);
617    assertTrue(func instanceof GeneratorFunction);
618    assertTrue(func instanceof A);
619    checkPrototypeChain(func, [A, GeneratorFunction, Function, Object]);
620    if (!is_strong) {
621      assertEquals(42, func.a);
622      assertEquals(4.2, func.d);
623      assertEquals(153, func.o.foo);
624
625      assertTrue(undefined !== func.prototype);
626      func.prototype.bar = "func.bar";
627      var obj = func();  // Generator object.
628      assertTrue(obj instanceof Object);
629      assertTrue(obj instanceof func);
630      assertEquals("object", typeof obj);
631      assertEquals("func.bar", obj.bar);
632      delete func.prototype.bar;
633
634      assertPropertiesEqual({done: false, value: 1}, obj.next());
635      assertPropertiesEqual({done: false, value: 1}, obj.next());
636      assertPropertiesEqual({done: false, value: 2}, obj.next());
637      assertPropertiesEqual({done: false, value: 3}, obj.next());
638      assertPropertiesEqual({done: false, value: 5}, obj.next());
639      assertPropertiesEqual({done: false, value: 8}, obj.next());
640      assertPropertiesEqual({done: true, value: undefined}, obj.next());
641    }
642  }
643
644  var source = "yield 1; yield 1; yield 2; yield 3; yield 5; yield 8;";
645
646  // Sloppy generator function
647  var sloppy_func = new A(source);
648  assertTrue(undefined !== sloppy_func.prototype);
649  CheckFunction(sloppy_func, false);
650
651  var sloppy_func1 = new A("yield 312;");
652  assertTrue(%HaveSameMap(sloppy_func, sloppy_func1));
653
654  // Strict generator function
655  var strict_func = new A("'use strict'; " + source);
656  assertFalse(%HaveSameMap(strict_func, sloppy_func));
657  CheckFunction(strict_func, false);
658
659  var strict_func1 = new A("'use strict'; yield 312;");
660  assertTrue(%HaveSameMap(strict_func, strict_func1));
661
662  // Strong generator function
663  var strong_func = new A("'use strong'; " + source);
664  assertFalse(%HaveSameMap(strong_func, sloppy_func));
665  assertFalse(%HaveSameMap(strong_func, strict_func));
666  CheckFunction(strong_func, true);
667
668  var strong_func1 = new A("'use strong'; yield 312;");
669  assertTrue(%HaveSameMap(strong_func, strong_func1));
670
671  gc();
672})();
673
674
675(function() {
676  class A extends Promise {
677    constructor(...args) {
678      assertFalse(new.target === undefined);
679      super(...args);
680      this.a = 42;
681      this.d = 4.2;
682      this.o = {foo:153};
683    }
684  }
685
686  var o = new A(function(resolve, reject) {
687    resolve("ok");
688  });
689  assertTrue(o instanceof Object);
690  assertTrue(o instanceof Promise);
691  assertTrue(o instanceof A);
692  assertEquals("object", typeof o);
693  checkPrototypeChain(o, [A, Promise, Object]);
694  assertEquals(42, o.a);
695  assertEquals(4.2, o.d);
696  assertEquals(153, o.o.foo);
697  o.then(
698      function(val) { assertEquals("ok", val); },
699      function(reason) { assertUnreachable(); })
700    .catch(function(reason) { %AbortJS("catch handler called: " + reason); });
701
702  var o1 = new A(function(resolve, reject) {
703    reject("fail");
704  });
705  o1.then(
706      function(val) { assertUnreachable(); },
707      function(reason) { assertEquals("fail", reason); })
708    .catch(function(reason) { %AbortJS("catch handler called: " + reason); });
709  assertTrue(%HaveSameMap(o, o1));
710
711  gc();
712})();
713
714
715(function() {
716  class A extends Boolean {
717    constructor() {
718      assertFalse(new.target === undefined);
719      super(true);
720      this.a00 = 0
721      this.a01 = 0
722      this.a02 = 0
723      this.a03 = 0
724      this.a04 = 0
725      this.a05 = 0
726      this.a06 = 0
727      this.a07 = 0
728      this.a08 = 0
729      this.a09 = 0
730      this.a10 = 0
731      this.a11 = 0
732      this.a12 = 0
733      this.a13 = 0
734      this.a14 = 0
735      this.a15 = 0
736      this.a16 = 0
737      this.a17 = 0
738      this.a18 = 0
739      this.a19 = 0
740    }
741  }
742
743  class B extends A {
744    constructor() {
745      assertFalse(new.target === undefined);
746      super();
747      this.b00 = 0
748      this.b01 = 0
749      this.b02 = 0
750      this.b03 = 0
751      this.b04 = 0
752      this.b05 = 0
753      this.b06 = 0
754      this.b07 = 0
755      this.b08 = 0
756      this.b09 = 0
757      this.b10 = 0
758      this.b11 = 0
759      this.b12 = 0
760      this.b13 = 0
761      this.b14 = 0
762      this.b15 = 0
763      this.b16 = 0
764      this.b17 = 0
765      this.b18 = 0
766      this.b19 = 0
767    }
768  }
769
770  class C extends B {
771    constructor() {
772      assertFalse(new.target === undefined);
773      super();
774      this.c00 = 0
775      this.c01 = 0
776      this.c02 = 0
777      this.c03 = 0
778      this.c04 = 0
779      this.c05 = 0
780      this.c06 = 0
781      this.c07 = 0
782      this.c08 = 0
783      this.c09 = 0
784      this.c10 = 0
785      this.c11 = 0
786      this.c12 = 0
787      this.c13 = 0
788      this.c14 = 0
789      this.c15 = 0
790      this.c16 = 0
791      this.c17 = 0
792      this.c18 = 0
793      this.c19 = 0
794    }
795  }
796
797  var o = new C();
798  assertTrue(o instanceof Object);
799  assertTrue(o instanceof Boolean);
800  assertTrue(o instanceof A);
801  assertTrue(o instanceof B);
802  assertTrue(o instanceof C);
803  assertEquals("object", typeof o);
804  checkPrototypeChain(o, [C, B, A, Boolean, Object]);
805
806  gc();
807})();
808
809
810(function() {
811  assertThrows("class A extends undefined {}");
812  assertThrows("class B extends NaN {}");
813  assertThrows("class C extends Infinity {}");
814})();
815
816
817(function() {
818  class A extends null {}
819  assertThrows("new A");
820})();
821
822
823(function() {
824  class A extends Symbol {}
825  assertThrows("new A");
826})();
827
828
829(function() {
830  function f() {}
831
832  var p = f.prototype;
833  var p2 = {};
834  var o = Reflect.construct(
835        Number, [{valueOf() { f.prototype=p2; return 10; }}], f);
836
837  assertTrue(o.__proto__ === f.prototype);
838  assertTrue(p2 === f.prototype);
839  assertFalse(p === o.__proto__);
840  assertEquals(10, Number.prototype.valueOf.call(o));
841})();
842
843
844(function() {
845  function f() {}
846
847  var p = f.prototype;
848  var p2 = {};
849  var o = Reflect.construct(
850        String, [{toString() { f.prototype=p2; return "biep"; }}], f);
851
852  assertTrue(o.__proto__ === f.prototype);
853  assertTrue(p2 === o.__proto__);
854  assertFalse(p === o.__proto__);
855  assertEquals("biep", String.prototype.toString.call(o));
856})();
857
858
859(function() {
860  function f() {}
861
862  var p = f.prototype;
863  var p2 = {};
864  var o = Reflect.construct(
865        Date, [{valueOf() { f.prototype=p2; return 1447836899614; }}], f);
866
867  assertTrue(o.__proto__ === f.prototype);
868  assertTrue(p2 === f.prototype);
869  assertFalse(p === o.__proto__);
870  assertEquals(new Date(1447836899614).toString(),
871               Date.prototype.toString.call(o));
872})();
873
874
875(function() {
876  function f() {}
877
878  var p = f.prototype;
879  var p2 = {};
880  var o = Reflect.construct(
881        Date, [2015, {valueOf() { f.prototype=p2; return 10; }}], f);
882
883  assertTrue(o.__proto__ === f.prototype);
884  assertTrue(p2 === f.prototype);
885  assertFalse(p === o.__proto__);
886  assertEquals(new Date(2015, 10).getYear(), Date.prototype.getYear.call(o));
887  assertEquals(new Date(2015, 10).getMonth(), Date.prototype.getMonth.call(o));
888})();
889
890
891(function() {
892  function f() {}
893
894  var p = f.prototype;
895  var p2 = {};
896  var o = Reflect.construct(
897        DataView, [new ArrayBuffer(100),
898                   {valueOf(){ f.prototype=p2; return 5; }}], f);
899
900  var byteOffset = Object.getOwnPropertyDescriptor(
901      DataView.prototype, "byteOffset").get;
902  var byteLength = Object.getOwnPropertyDescriptor(
903      DataView.prototype, "byteLength").get;
904
905  assertTrue(o.__proto__ === f.prototype);
906  assertTrue(p2 === f.prototype);
907  assertFalse(p === o.__proto__);
908  assertEquals(5, byteOffset.call(o));
909  assertEquals(95, byteLength.call(o));
910})();
911
912
913(function() {
914  function f() {}
915
916  var p = f.prototype;
917  var p2 = {};
918  var o = Reflect.construct(
919        DataView, [new ArrayBuffer(100),
920                   30, {valueOf() { f.prototype=p2; return 5; }}], f);
921
922  var byteOffset = Object.getOwnPropertyDescriptor(
923      DataView.prototype, "byteOffset").get;
924  var byteLength = Object.getOwnPropertyDescriptor(
925      DataView.prototype, "byteLength").get;
926
927  assertTrue(o.__proto__ === f.prototype);
928  assertTrue(p2 === f.prototype);
929  assertFalse(p === o.__proto__);
930  assertEquals(30, byteOffset.call(o));
931  assertEquals(5, byteLength.call(o));
932})();
933
934
935(function() {
936  function f() {}
937
938  var p = f.prototype;
939  var p2 = {};
940  var p3 = {};
941
942  var log = [];
943
944  var pattern = {toString() {
945    log.push("tostring");
946    f.prototype = p3; return "biep" }};
947
948  Object.defineProperty(pattern, Symbol.match, {
949    get() { log.push("match"); f.prototype = p2; return false; }});
950
951  var o = Reflect.construct(RegExp, [pattern], f);
952  assertEquals(["match", "tostring"], log);
953  assertEquals(/biep/, o);
954  assertTrue(o.__proto__ === p2);
955  assertTrue(f.prototype === p3);
956})();
957