v8/test/mjsunit/es6/classes-subclass-builtins.js
littledan 07c91dccbe Use ES2015-style TypedArray prototype chain
This patch switches TypedArrays to use the prototype chain described
in the ES2015 specification, which adds a %TypedArray% superclass above
all individual TypedArray types. Most methods are defined on the
superclass rather than the subclasses.

In order to prevent a performance regression, a few methods are
marked as inline. Inlining might prevent code which was previously
monomorphic from becoming polymorphic, and it was specifically
applied in places where methods became more polymorphic than before.
Tests with realistic workloads would be nice to do before this
ships in stable.

This patch does not bring TypedArrays up to full spec compliance. In
particular, @@species is not yet supported.

R=cbruni
BUG=v8:4085
LOG=Y

Review URL: https://codereview.chromium.org/1541233002

Cr-Commit-Position: refs/heads/master@{#33050}
2015-12-28 17:28:54 +00:00

957 lines
23 KiB
JavaScript

// Copyright 2015 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 --harmony-reflect --harmony-regexp-subclass
// Flags: --expose-gc --strong-mode
"use strict";
function checkPrototypeChain(object, constructors) {
var proto = object.__proto__;
for (var i = 0; i < constructors.length; i++) {
assertEquals(constructors[i].prototype, proto);
assertEquals(constructors[i], proto.constructor);
proto = proto.__proto__;
}
}
(function() {
class A extends Object {
constructor(...args) {
assertFalse(new.target === undefined);
super(...args);
this.a = 42;
this.d = 4.2;
this.o = {foo:153};
}
}
var s = new A("foo");
assertTrue(s instanceof Object);
assertTrue(s instanceof A);
assertEquals("object", typeof s);
checkPrototypeChain(s, [A, Object]);
assertEquals(42, s.a);
assertEquals(4.2, s.d);
assertEquals(153, s.o.foo);
var s1 = new A("bar");
assertTrue(%HaveSameMap(s, s1));
var n = new A(153);
assertTrue(n instanceof Object);
assertTrue(n instanceof A);
assertEquals("object", typeof s);
checkPrototypeChain(s, [A, Object]);
assertEquals(42, n.a);
assertEquals(4.2, n.d);
assertEquals(153, n.o.foo);
var n1 = new A(312);
assertTrue(%HaveSameMap(n, n1));
assertTrue(%HaveSameMap(n, s));
var b = new A(true);
assertTrue(b instanceof Object);
assertTrue(b instanceof A);
assertEquals("object", typeof s);
checkPrototypeChain(s, [A, Object]);
assertEquals(42, b.a);
assertEquals(4.2, b.d);
assertEquals(153, b.o.foo);
var b1 = new A(true);
assertTrue(%HaveSameMap(b, b1));
assertTrue(%HaveSameMap(b, s));
gc();
})();
(function() {
class A extends Function {
constructor(...args) {
assertFalse(new.target === undefined);
super(...args);
// Strong functions are not extensible, so don't add fields.
if (args[args.length - 1].indexOf("use strong") >= 0) {
assertThrows(()=>{ this.a = 10; }, TypeError);
return;
}
this.a = 42;
this.d = 4.2;
this.o = {foo:153};
}
}
var sloppy_func = new A("");
var strict_func = new A("'use strict';");
assertNull(sloppy_func.caller);
assertThrows("strict_f.caller");
assertNull(Object.getOwnPropertyDescriptor(sloppy_func, "caller").value);
assertEquals(undefined, Object.getOwnPropertyDescriptor(strict_func, "caller"));
function CheckFunction(func, is_strong) {
assertEquals("function", typeof func);
assertTrue(func instanceof Object);
assertTrue(func instanceof Function);
assertTrue(func instanceof A);
checkPrototypeChain(func, [A, Function, Object]);
if (!is_strong) {
assertEquals(42, func.a);
assertEquals(4.2, func.d);
assertEquals(153, func.o.foo);
assertTrue(undefined !== func.prototype);
func.prototype.bar = "func.bar";
var obj = new func();
assertTrue(obj instanceof Object);
assertTrue(obj instanceof func);
assertEquals("object", typeof obj);
assertEquals(113, obj.foo);
assertEquals("func.bar", obj.bar);
delete func.prototype.bar;
}
}
var source = "this.foo = 113;";
// Sloppy function
var sloppy_func = new A(source);
assertTrue(undefined !== sloppy_func.prototype);
CheckFunction(sloppy_func, false);
var sloppy_func1 = new A("return 312;");
assertTrue(%HaveSameMap(sloppy_func, sloppy_func1));
// Strict function
var strict_func = new A("'use strict'; " + source);
assertFalse(%HaveSameMap(strict_func, sloppy_func));
CheckFunction(strict_func, false);
var strict_func1 = new A("'use strict'; return 312;");
assertTrue(%HaveSameMap(strict_func, strict_func1));
// Strong function
var strong_func = new A("'use strong'; " + source);
assertFalse(%HaveSameMap(strong_func, sloppy_func));
assertFalse(%HaveSameMap(strong_func, strict_func));
CheckFunction(strong_func, true);
var strong_func1 = new A("'use strong'; return 312;");
assertTrue(%HaveSameMap(strong_func, strong_func1));
gc();
})();
(function() {
class A extends Boolean {
constructor(...args) {
assertFalse(new.target === undefined);
super(...args);
this.a = 42;
this.d = 4.2;
this.o = {foo:153};
}
}
var o = new A(true);
assertTrue(o instanceof Object);
assertTrue(o instanceof Boolean);
assertTrue(o instanceof A);
assertEquals("object", typeof o);
checkPrototypeChain(o, [A, Boolean]);
assertTrue(o.valueOf());
assertEquals(42, o.a);
assertEquals(4.2, o.d);
assertEquals(153, o.o.foo);
var o1 = new A(false);
assertTrue(%HaveSameMap(o, o1));
gc();
})();
function TestErrorSubclassing(error) {
class A extends error {
constructor(...args) {
assertFalse(new.target === undefined);
super(...args);
this.a = 42;
this.d = 4.2;
this.o = {foo:153};
}
}
var o = new A("message");
assertTrue(o instanceof Object);
assertTrue(o instanceof error);
assertTrue(o instanceof Error);
assertTrue(o instanceof A);
assertEquals("object", typeof o);
if (error == Error) {
checkPrototypeChain(o, [A, Error, Object]);
} else {
checkPrototypeChain(o, [A, error, Error, Object]);
}
assertEquals("message", o.message);
assertEquals(error.name + ": message", o.toString());
assertEquals(42, o.a);
assertEquals(4.2, o.d);
assertEquals(153, o.o.foo);
var o1 = new A("achtung!");
assertTrue(%HaveSameMap(o, o1));
gc();
}
(function() {
TestErrorSubclassing(Error);
TestErrorSubclassing(EvalError);
TestErrorSubclassing(RangeError);
TestErrorSubclassing(ReferenceError);
TestErrorSubclassing(SyntaxError);
TestErrorSubclassing(TypeError);
TestErrorSubclassing(URIError);
})();
(function() {
class A extends Number {
constructor(...args) {
assertFalse(new.target === undefined);
super(...args);
this.a = 42;
this.d = 4.2;
this.o = {foo:153};
}
}
var o = new A(153);
assertTrue(o instanceof Object);
assertTrue(o instanceof Number);
assertTrue(o instanceof A);
assertEquals("object", typeof o);
checkPrototypeChain(o, [A, Number, Object]);
assertEquals(153, o.valueOf());
assertEquals(42, o.a);
assertEquals(4.2, o.d);
assertEquals(153, o.o.foo);
var o1 = new A(312);
assertTrue(%HaveSameMap(o, o1));
gc();
})();
(function() {
class A extends Date {
constructor(...args) {
assertFalse(new.target === undefined);
super(...args);
this.a = 42;
this.d = 4.2;
this.o = {foo:153};
}
}
var o = new A(1234567890);
assertTrue(o instanceof Object);
assertTrue(o instanceof Date);
assertTrue(o instanceof A);
assertEquals("object", typeof o);
checkPrototypeChain(o, [A, Date, Object]);
assertEquals(1234567890, o.getTime());
assertEquals(42, o.a);
assertEquals(4.2, o.d);
assertEquals(153, o.o.foo);
var o1 = new A(2015, 10, 29);
assertEquals(2015, o1.getFullYear());
assertEquals(10, o1.getMonth());
assertEquals(29, o1.getDate());
assertTrue(%HaveSameMap(o, o1));
gc();
})();
(function() {
class A extends String {
constructor(...args) {
assertFalse(new.target === undefined);
super(...args);
this.a = 42;
this.d = 4.2;
this.o = {foo:153};
}
}
var o = new A("foo");
assertTrue(o instanceof Object);
assertTrue(o instanceof String);
assertTrue(o instanceof A);
assertEquals("object", typeof o);
checkPrototypeChain(o, [A, String, Object]);
assertEquals("foo", o.valueOf());
assertEquals(42, o.a);
assertEquals(4.2, o.d);
assertEquals(153, o.o.foo);
var o1 = new A("bar");
assertTrue(%HaveSameMap(o, o1));
gc();
})();
(function() {
class A extends RegExp {
constructor(...args) {
assertFalse(new.target === undefined);
super(...args);
this.a = 42;
this.d = 4.2;
this.o = {foo:153};
}
}
var o = new A("o(..)h", "g");
assertTrue(o instanceof Object);
assertTrue(o instanceof RegExp);
assertTrue(o instanceof A);
assertEquals("object", typeof o);
checkPrototypeChain(o, [A, RegExp, Object]);
assertTrue(o.test("ouch"));
assertArrayEquals(["ouch", "uc"], o.exec("boom! ouch! bam!"));
assertEquals("o(..)h", o.source);
assertTrue(o.global);
assertFalse(o.ignoreCase);
assertFalse(o.multiline);
assertEquals(10, o.lastIndex);
assertEquals(42, o.a);
assertEquals(4.2, o.d);
assertEquals(153, o.o.foo);
var o1 = new A(7);
assertTrue(%HaveSameMap(o, o1));
gc();
})();
(function TestArraySubclassing() {
class A extends Array {
constructor(...args) {
assertFalse(new.target === undefined);
super(...args);
this.a = 42;
this.d = 4.2;
this.o = {foo:153};
}
}
var o = new Array(13);
assertTrue(o instanceof Object);
assertTrue(o instanceof Array);
assertEquals("object", typeof o);
checkPrototypeChain(o, [Array, Object]);
assertEquals(13, o.length);
var o = new A(10);
assertTrue(o instanceof Object);
assertTrue(o instanceof Array);
assertTrue(o instanceof A);
assertEquals("object", typeof o);
checkPrototypeChain(o, [A, Array, Object]);
assertEquals(10, o.length);
assertEquals(42, o.a);
assertEquals(4.2, o.d);
assertEquals(153, o.o.foo);
var o1 = new A(7);
assertTrue(%HaveSameMap(o, o1));
})();
var TypedArray = Uint8Array.__proto__;
function TestTypedArraySubclassing(array) {
class A extends array {
constructor(...args) {
assertFalse(new.target === undefined);
super(...args);
this.a = 42;
this.d = 4.2;
this.o = {foo:153};
}
}
var o = new array(13);
assertTrue(o instanceof Object);
assertTrue(o instanceof TypedArray);
assertTrue(o instanceof array);
assertEquals("object", typeof o);
checkPrototypeChain(o, [array, TypedArray, Object]);
assertEquals(13, o.length);
var o = new A(10);
assertTrue(o instanceof Object);
assertTrue(o instanceof TypedArray);
assertTrue(o instanceof array);
assertTrue(o instanceof A);
assertEquals("object", typeof o);
checkPrototypeChain(o, [A, array, TypedArray, Object]);
assertEquals(10, o.length);
assertEquals(42, o.a);
assertEquals(4.2, o.d);
assertEquals(153, o.o.foo);
var o1 = new A(7);
assertTrue(%HaveSameMap(o, o1));
}
(function() {
TestTypedArraySubclassing(Int8Array);
TestTypedArraySubclassing(Uint8Array);
TestTypedArraySubclassing(Uint8ClampedArray);
TestTypedArraySubclassing(Int16Array);
TestTypedArraySubclassing(Uint16Array);
TestTypedArraySubclassing(Int32Array);
TestTypedArraySubclassing(Uint32Array);
TestTypedArraySubclassing(Float32Array);
TestTypedArraySubclassing(Float64Array);
})();
function TestMapSetSubclassing(container, is_map) {
var keys = [{name: "banana"}, {name: "cow"}, {name: "orange"}, {name: "chicken"}, {name: "apple"}];
class A extends container {
constructor(...args) {
assertFalse(new.target === undefined);
super(...args);
this.a = 42;
this.d = 4.2;
this.o = {foo:153};
}
}
var o = new A();
assertTrue(o instanceof Object);
assertTrue(o instanceof container);
assertTrue(o instanceof A);
assertEquals("object", typeof o);
checkPrototypeChain(o, [A, container, Object]);
for (var i = 0; i < keys.length; i++) {
if (is_map) {
o.set(keys[i], (i + 1) * 11);
} else {
o.add(keys[i]);
}
}
o.delete(keys[1]);
o.delete(keys[3]);
assertTrue(o.has(keys[0]));
assertFalse(o.has(keys[1]));
assertTrue(o.has(keys[2]));
assertFalse(o.has(keys[1]));
assertTrue(o.has(keys[4]));
if (is_map) {
assertEquals(11, o.get(keys[0]));
assertEquals(undefined, o.get(keys[1]));
assertEquals(33, o.get(keys[2]));
assertEquals(undefined, o.get(keys[3]));
assertEquals(55, o.get(keys[4]));
}
assertEquals(42, o.a);
assertEquals(4.2, o.d);
assertEquals(153, o.o.foo);
var o1 = new A();
assertTrue(%HaveSameMap(o, o1));
gc();
}
(function() {
TestMapSetSubclassing(Map, true);
TestMapSetSubclassing(WeakMap, true);
TestMapSetSubclassing(Set, false);
TestMapSetSubclassing(WeakSet, false);
})();
(function() {
class A extends ArrayBuffer {
constructor(...args) {
assertFalse(new.target === undefined);
super(...args);
this.a = 42;
this.d = 4.2;
this.o = {foo:153};
}
}
var o = new A(16);
assertTrue(o instanceof Object);
assertTrue(o instanceof ArrayBuffer);
assertTrue(o instanceof A);
assertEquals("object", typeof o);
checkPrototypeChain(o, [A, ArrayBuffer, Object]);
assertEquals(16, o.byteLength);
assertEquals(42, o.a);
assertEquals(4.2, o.d);
assertEquals(153, o.o.foo);
var o1 = new A("bar");
assertTrue(%HaveSameMap(o, o1));
class MyInt32Array extends Int32Array {
constructor(v, name) {
super(v);
this.name = name;
}
}
class MyUint32Array extends Uint32Array {
constructor(v, name) {
super(v);
this.name = name;
}
}
var int32view = new MyInt32Array(o, "cats");
var uint32view = new MyUint32Array(o, "dogs");
int32view[0] = -2;
uint32view[1] = 0xffffffff;
assertEquals("cats", int32view.name);
assertEquals("dogs", uint32view.name);
assertEquals(-2, int32view[0]);
assertEquals(-1, int32view[1]);
assertEquals(0xfffffffe, uint32view[0]);
assertEquals(0xffffffff, uint32view[1]);
gc();
})();
(function() {
class A extends DataView {
constructor(...args) {
assertFalse(new.target === undefined);
super(...args);
this.a = 42;
this.d = 4.2;
this.o = {foo:153};
}
}
var buffer = new ArrayBuffer(16);
var o = new A(buffer);
assertTrue(o instanceof Object);
assertTrue(o instanceof DataView);
assertTrue(o instanceof A);
assertEquals("object", typeof o);
checkPrototypeChain(o, [A, DataView, Object]);
o.setUint32(0, 0xcafebabe, false);
assertEquals(0xcafebabe, o.getUint32(0, false));
assertEquals(0xbebafeca, o.getUint32(0, true));
assertEquals(42, o.a);
assertEquals(4.2, o.d);
assertEquals(153, o.o.foo);
var o1 = new A(buffer);
assertTrue(%HaveSameMap(o, o1));
gc();
})();
(function() {
var GeneratorFunction = (function*() {}).constructor;
class A extends GeneratorFunction {
constructor(...args) {
assertFalse(new.target === undefined);
super(...args);
// Strong functions are not extensible, so don't add fields.
if (args[args.length - 1].indexOf("use strong") >= 0) {
assertThrows(()=>{ this.a = 10; }, TypeError);
return;
}
this.a = 42;
this.d = 4.2;
this.o = {foo:153};
}
}
var sloppy_func = new A("yield 153;");
var strict_func = new A("'use strict'; yield 153;");
// Unfortunately the difference is not observable from outside.
assertThrows("sloppy_func.caller");
assertThrows("strict_f.caller");
assertEquals(undefined, Object.getOwnPropertyDescriptor(sloppy_func, "caller"));
assertEquals(undefined, Object.getOwnPropertyDescriptor(strict_func, "caller"));
function CheckFunction(func, is_strong) {
assertEquals("function", typeof func);
assertTrue(func instanceof Object);
assertTrue(func instanceof Function);
assertTrue(func instanceof GeneratorFunction);
assertTrue(func instanceof A);
checkPrototypeChain(func, [A, GeneratorFunction, Function, Object]);
if (!is_strong) {
assertEquals(42, func.a);
assertEquals(4.2, func.d);
assertEquals(153, func.o.foo);
assertTrue(undefined !== func.prototype);
func.prototype.bar = "func.bar";
var obj = func(); // Generator object.
assertTrue(obj instanceof Object);
assertTrue(obj instanceof func);
assertEquals("object", typeof obj);
assertEquals("func.bar", obj.bar);
delete func.prototype.bar;
assertPropertiesEqual({done: false, value: 1}, obj.next());
assertPropertiesEqual({done: false, value: 1}, obj.next());
assertPropertiesEqual({done: false, value: 2}, obj.next());
assertPropertiesEqual({done: false, value: 3}, obj.next());
assertPropertiesEqual({done: false, value: 5}, obj.next());
assertPropertiesEqual({done: false, value: 8}, obj.next());
assertPropertiesEqual({done: true, value: undefined}, obj.next());
}
}
var source = "yield 1; yield 1; yield 2; yield 3; yield 5; yield 8;";
// Sloppy generator function
var sloppy_func = new A(source);
assertTrue(undefined !== sloppy_func.prototype);
CheckFunction(sloppy_func, false);
var sloppy_func1 = new A("yield 312;");
assertTrue(%HaveSameMap(sloppy_func, sloppy_func1));
// Strict generator function
var strict_func = new A("'use strict'; " + source);
assertFalse(%HaveSameMap(strict_func, sloppy_func));
CheckFunction(strict_func, false);
var strict_func1 = new A("'use strict'; yield 312;");
assertTrue(%HaveSameMap(strict_func, strict_func1));
// Strong generator function
var strong_func = new A("'use strong'; " + source);
assertFalse(%HaveSameMap(strong_func, sloppy_func));
assertFalse(%HaveSameMap(strong_func, strict_func));
CheckFunction(strong_func, true);
var strong_func1 = new A("'use strong'; yield 312;");
assertTrue(%HaveSameMap(strong_func, strong_func1));
gc();
})();
(function() {
class A extends Promise {
constructor(...args) {
assertFalse(new.target === undefined);
super(...args);
this.a = 42;
this.d = 4.2;
this.o = {foo:153};
}
}
var o = new A(function(resolve, reject) {
resolve("ok");
});
assertTrue(o instanceof Object);
assertTrue(o instanceof Promise);
assertTrue(o instanceof A);
assertEquals("object", typeof o);
checkPrototypeChain(o, [A, Promise, Object]);
assertEquals(42, o.a);
assertEquals(4.2, o.d);
assertEquals(153, o.o.foo);
o.then(
function(val) { assertEquals("ok", val); },
function(reason) { assertUnreachable(); })
.catch(function(reason) { %AbortJS("catch handler called: " + reason); });
var o1 = new A(function(resolve, reject) {
reject("fail");
});
o1.then(
function(val) { assertUnreachable(); },
function(reason) { assertEquals("fail", reason); })
.catch(function(reason) { %AbortJS("catch handler called: " + reason); });
assertTrue(%HaveSameMap(o, o1));
gc();
})();
(function() {
class A extends Boolean {
constructor() {
assertFalse(new.target === undefined);
super(true);
this.a00 = 0
this.a01 = 0
this.a02 = 0
this.a03 = 0
this.a04 = 0
this.a05 = 0
this.a06 = 0
this.a07 = 0
this.a08 = 0
this.a09 = 0
this.a10 = 0
this.a11 = 0
this.a12 = 0
this.a13 = 0
this.a14 = 0
this.a15 = 0
this.a16 = 0
this.a17 = 0
this.a18 = 0
this.a19 = 0
}
}
class B extends A {
constructor() {
assertFalse(new.target === undefined);
super();
this.b00 = 0
this.b01 = 0
this.b02 = 0
this.b03 = 0
this.b04 = 0
this.b05 = 0
this.b06 = 0
this.b07 = 0
this.b08 = 0
this.b09 = 0
this.b10 = 0
this.b11 = 0
this.b12 = 0
this.b13 = 0
this.b14 = 0
this.b15 = 0
this.b16 = 0
this.b17 = 0
this.b18 = 0
this.b19 = 0
}
}
class C extends B {
constructor() {
assertFalse(new.target === undefined);
super();
this.c00 = 0
this.c01 = 0
this.c02 = 0
this.c03 = 0
this.c04 = 0
this.c05 = 0
this.c06 = 0
this.c07 = 0
this.c08 = 0
this.c09 = 0
this.c10 = 0
this.c11 = 0
this.c12 = 0
this.c13 = 0
this.c14 = 0
this.c15 = 0
this.c16 = 0
this.c17 = 0
this.c18 = 0
this.c19 = 0
}
}
var o = new C();
assertTrue(o instanceof Object);
assertTrue(o instanceof Boolean);
assertTrue(o instanceof A);
assertTrue(o instanceof B);
assertTrue(o instanceof C);
assertEquals("object", typeof o);
checkPrototypeChain(o, [C, B, A, Boolean, Object]);
gc();
})();
(function() {
assertThrows("class A extends undefined {}");
assertThrows("class B extends NaN {}");
assertThrows("class C extends Infinity {}");
})();
(function() {
class A extends null {}
assertThrows("new A");
})();
(function() {
class A extends Symbol {}
assertThrows("new A");
})();
(function() {
function f() {}
var p = f.prototype;
var p2 = {};
var o = Reflect.construct(
Number, [{valueOf() { f.prototype=p2; return 10; }}], f);
assertTrue(o.__proto__ === f.prototype);
assertTrue(p2 === f.prototype);
assertFalse(p === o.__proto__);
assertEquals(10, Number.prototype.valueOf.call(o));
})();
(function() {
function f() {}
var p = f.prototype;
var p2 = {};
var o = Reflect.construct(
String, [{toString() { f.prototype=p2; return "biep"; }}], f);
assertTrue(o.__proto__ === f.prototype);
assertTrue(p2 === o.__proto__);
assertFalse(p === o.__proto__);
assertEquals("biep", String.prototype.toString.call(o));
})();
(function() {
function f() {}
var p = f.prototype;
var p2 = {};
var o = Reflect.construct(
Date, [{valueOf() { f.prototype=p2; return 1447836899614; }}], f);
assertTrue(o.__proto__ === f.prototype);
assertTrue(p2 === f.prototype);
assertFalse(p === o.__proto__);
assertEquals(new Date(1447836899614).toString(),
Date.prototype.toString.call(o));
})();
(function() {
function f() {}
var p = f.prototype;
var p2 = {};
var o = Reflect.construct(
Date, [2015, {valueOf() { f.prototype=p2; return 10; }}], f);
assertTrue(o.__proto__ === f.prototype);
assertTrue(p2 === f.prototype);
assertFalse(p === o.__proto__);
assertEquals(new Date(2015, 10).getYear(), Date.prototype.getYear.call(o));
assertEquals(new Date(2015, 10).getMonth(), Date.prototype.getMonth.call(o));
})();
(function() {
function f() {}
var p = f.prototype;
var p2 = {};
var o = Reflect.construct(
DataView, [new ArrayBuffer(100),
{valueOf(){ f.prototype=p2; return 5; }}], f);
var byteOffset = Object.getOwnPropertyDescriptor(
DataView.prototype, "byteOffset").get;
var byteLength = Object.getOwnPropertyDescriptor(
DataView.prototype, "byteLength").get;
assertTrue(o.__proto__ === f.prototype);
assertTrue(p2 === f.prototype);
assertFalse(p === o.__proto__);
assertEquals(5, byteOffset.call(o));
assertEquals(95, byteLength.call(o));
})();
(function() {
function f() {}
var p = f.prototype;
var p2 = {};
var o = Reflect.construct(
DataView, [new ArrayBuffer(100),
30, {valueOf() { f.prototype=p2; return 5; }}], f);
var byteOffset = Object.getOwnPropertyDescriptor(
DataView.prototype, "byteOffset").get;
var byteLength = Object.getOwnPropertyDescriptor(
DataView.prototype, "byteLength").get;
assertTrue(o.__proto__ === f.prototype);
assertTrue(p2 === f.prototype);
assertFalse(p === o.__proto__);
assertEquals(30, byteOffset.call(o));
assertEquals(5, byteLength.call(o));
})();
(function() {
function f() {}
var p = f.prototype;
var p2 = {};
var p3 = {};
var log = [];
var pattern = {toString() {
log.push("tostring");
f.prototype = p3; return "biep" }};
Object.defineProperty(pattern, Symbol.match, {
get() { log.push("match"); f.prototype = p2; return false; }});
var o = Reflect.construct(RegExp, [pattern], f);
assertEquals(["match", "tostring"], log);
assertEquals(/biep/, o);
assertTrue(o.__proto__ === p2);
assertTrue(f.prototype === p3);
})();