293 lines
5.7 KiB
JavaScript
293 lines
5.7 KiB
JavaScript
|
// Copyright 2018 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.
|
||
|
|
||
|
{
|
||
|
class X {
|
||
|
#x = 1;
|
||
|
getX(arg) { return arg.#x; }
|
||
|
setX(arg, val) { arg.#x = val; }
|
||
|
}
|
||
|
|
||
|
let x1 = new X;
|
||
|
let y = new class {};
|
||
|
|
||
|
// IC: 0 -> Error
|
||
|
assertThrows(() => x1.getX(y), TypeError);
|
||
|
assertThrows(() => x1.getX(y), TypeError);
|
||
|
assertThrows(() => x1.getX(y), TypeError);
|
||
|
|
||
|
assertThrows(() => x1.setX(y, 2), TypeError);
|
||
|
assertThrows(() => x1.setX(y, 3), TypeError);
|
||
|
assertThrows(() => x1.setX(y, 4), TypeError);
|
||
|
|
||
|
// IC: 0 -> Monomorphic
|
||
|
assertEquals(1, x1.getX(x1));
|
||
|
assertEquals(1, x1.getX(x1));
|
||
|
assertEquals(1, x1.getX(x1));
|
||
|
|
||
|
x1.setX(x1, 2);
|
||
|
x1.setX(x1, 3);
|
||
|
x1.setX(x1, 4);
|
||
|
}
|
||
|
|
||
|
{
|
||
|
class X {
|
||
|
#x = 1;
|
||
|
getX(arg) { return arg.#x; }
|
||
|
setX(arg, val) { arg.#x = val; }
|
||
|
}
|
||
|
|
||
|
let x1 = new X;
|
||
|
// IC: 0 -> Monomorphic
|
||
|
assertEquals(1, x1.getX(x1));
|
||
|
assertEquals(1, x1.getX(x1));
|
||
|
assertEquals(1, x1.getX(x1));
|
||
|
|
||
|
x1.setX(x1, 2);
|
||
|
x1.setX(x1, 3);
|
||
|
x1.setX(x1, 4);
|
||
|
|
||
|
let y = new class {};
|
||
|
// IC: Monomorphic -> Error
|
||
|
assertThrows(() => x1.getX(y), TypeError);
|
||
|
assertThrows(() => x1.getX(y), TypeError);
|
||
|
assertThrows(() => x1.getX(y), TypeError);
|
||
|
|
||
|
assertThrows(() => x1.setX(y, 2), TypeError);
|
||
|
assertThrows(() => x1.setX(y, 3), TypeError);
|
||
|
assertThrows(() => x1.setX(y, 4), TypeError);
|
||
|
|
||
|
let x3 = new X;
|
||
|
// IC: Monomorphic -> Monomorphic
|
||
|
assertEquals(1, x1.getX(x3));
|
||
|
assertEquals(1, x1.getX(x3));
|
||
|
assertEquals(1, x1.getX(x3));
|
||
|
|
||
|
x1.setX(x3, 2);
|
||
|
x1.setX(x3, 3);
|
||
|
x1.setX(x3, 4);
|
||
|
}
|
||
|
|
||
|
|
||
|
{
|
||
|
class X {
|
||
|
#x = 1;
|
||
|
getX(arg) { return arg.#x; }
|
||
|
setX(arg, val) { arg.#x = val; }
|
||
|
}
|
||
|
|
||
|
let x1 = new X;
|
||
|
// IC: 0 -> Monomorphic
|
||
|
assertEquals(1, x1.getX(x1));
|
||
|
assertEquals(1, x1.getX(x1));
|
||
|
assertEquals(1, x1.getX(x1));
|
||
|
|
||
|
x1.setX(x1, 2);
|
||
|
x1.setX(x1, 3);
|
||
|
x1.setX(x1, 4);
|
||
|
|
||
|
class X2 extends X {
|
||
|
#x2 = 2;
|
||
|
}
|
||
|
|
||
|
let x2 = new X2;
|
||
|
// IC: Monomorphic -> Polymorphic
|
||
|
assertEquals(1, x1.getX(x2));
|
||
|
assertEquals(1, x1.getX(x2));
|
||
|
assertEquals(1, x1.getX(x2));
|
||
|
|
||
|
x1.setX(x2, 2);
|
||
|
x1.setX(x2, 3);
|
||
|
x1.setX(x2, 4);
|
||
|
|
||
|
let y = new class {};
|
||
|
|
||
|
// IC: Polymorphic -> Error
|
||
|
assertThrows(() => x1.getX(y), TypeError);
|
||
|
assertThrows(() => x1.getX(y), TypeError);
|
||
|
assertThrows(() => x1.getX(y), TypeError);
|
||
|
|
||
|
assertThrows(() => x1.setX(y, 2), TypeError);
|
||
|
assertThrows(() => x1.setX(y, 3), TypeError);
|
||
|
assertThrows(() => x1.setX(y, 4), TypeError);
|
||
|
|
||
|
class X3 extends X {
|
||
|
#x3 = 2;
|
||
|
}
|
||
|
|
||
|
let x3 = new X3;
|
||
|
// IC: Polymorphic -> Polymorphic
|
||
|
assertEquals(1, x1.getX(x3));
|
||
|
assertEquals(1, x1.getX(x3));
|
||
|
assertEquals(1, x1.getX(x3));
|
||
|
|
||
|
x1.setX(x3, 2);
|
||
|
x1.setX(x3, 3);
|
||
|
x1.setX(x3, 4);
|
||
|
}
|
||
|
|
||
|
{
|
||
|
class X {
|
||
|
#x = 1;
|
||
|
getX(arg) { return arg.#x; }
|
||
|
setX(arg, val) { arg.#x = val; }
|
||
|
}
|
||
|
|
||
|
let x1 = new X;
|
||
|
// IC: 0 -> Monomorphic
|
||
|
assertEquals(1, x1.getX(x1));
|
||
|
assertEquals(1, x1.getX(x1));
|
||
|
assertEquals(1, x1.getX(x1));
|
||
|
|
||
|
x1.setX(x1, 2);
|
||
|
x1.setX(x1, 3);
|
||
|
x1.setX(x1, 4);
|
||
|
|
||
|
class X2 extends X {
|
||
|
#x2 = 2;
|
||
|
}
|
||
|
|
||
|
let x2 = new X2;
|
||
|
// IC: Monomorphic -> Polymorphic
|
||
|
assertEquals(1, x1.getX(x2));
|
||
|
assertEquals(1, x1.getX(x2));
|
||
|
assertEquals(1, x1.getX(x2));
|
||
|
|
||
|
x1.setX(x2, 2);
|
||
|
x1.setX(x2, 3);
|
||
|
x1.setX(x2, 4);
|
||
|
|
||
|
class X3 extends X {
|
||
|
#x3 = 2;
|
||
|
}
|
||
|
|
||
|
let x3 = new X3;
|
||
|
assertEquals(1, x1.getX(x3));
|
||
|
assertEquals(1, x1.getX(x3));
|
||
|
assertEquals(1, x1.getX(x3));
|
||
|
|
||
|
x1.setX(x3, 2);
|
||
|
x1.setX(x3, 3);
|
||
|
x1.setX(x3, 4);
|
||
|
|
||
|
|
||
|
class X4 extends X {
|
||
|
#x4 = 2;
|
||
|
}
|
||
|
|
||
|
let x4 = new X4;
|
||
|
assertEquals(1, x1.getX(x4));
|
||
|
assertEquals(1, x1.getX(x4));
|
||
|
assertEquals(1, x1.getX(x4));
|
||
|
|
||
|
x1.setX(x4, 2);
|
||
|
x1.setX(x4, 3);
|
||
|
x1.setX(x4, 4);
|
||
|
|
||
|
class X5 extends X {
|
||
|
#x5 = 2;
|
||
|
}
|
||
|
|
||
|
let x5 = new X5;
|
||
|
// IC: Polymorphic -> Megamorphic
|
||
|
assertEquals(1, x1.getX(x5));
|
||
|
assertEquals(1, x1.getX(x5));
|
||
|
assertEquals(1, x1.getX(x5));
|
||
|
|
||
|
x1.setX(x5, 2);
|
||
|
x1.setX(x5, 3);
|
||
|
x1.setX(x5, 4);
|
||
|
|
||
|
let y = new class {};
|
||
|
|
||
|
// IC: Megamorphic -> Error
|
||
|
assertThrows(() => x1.getX(y), TypeError);
|
||
|
assertThrows(() => x1.getX(y), TypeError);
|
||
|
assertThrows(() => x1.getX(y), TypeError);
|
||
|
|
||
|
assertThrows(() => x1.setX(y, 2), TypeError);
|
||
|
assertThrows(() => x1.setX(y, 3), TypeError);
|
||
|
assertThrows(() => x1.setX(y, 4), TypeError);
|
||
|
|
||
|
class X6 extends X {
|
||
|
#x6 = 2;
|
||
|
}
|
||
|
|
||
|
let x6 = new X6;
|
||
|
// IC: Megamorphic -> Megamorphic
|
||
|
assertEquals(1, x1.getX(x6));
|
||
|
assertEquals(1, x1.getX(x6));
|
||
|
assertEquals(1, x1.getX(x6));
|
||
|
|
||
|
x1.setX(x6, 2);
|
||
|
x1.setX(x6, 3);
|
||
|
x1.setX(x6, 4);
|
||
|
}
|
||
|
|
||
|
{
|
||
|
class C {
|
||
|
#a = 1;
|
||
|
getA() { return this.#a; }
|
||
|
setA(v) { this.#a = v; }
|
||
|
}
|
||
|
|
||
|
let p = new Proxy(new C, {
|
||
|
get(target, name) {
|
||
|
return target[name];
|
||
|
},
|
||
|
|
||
|
set(target, name, val) {
|
||
|
target[name] = val;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
assertThrows(() => p.getA(), TypeError);
|
||
|
assertThrows(() => p.getA(), TypeError);
|
||
|
assertThrows(() => p.getA(), TypeError);
|
||
|
|
||
|
assertThrows(() => p.setA(2), TypeError);
|
||
|
assertThrows(() => p.setA(3), TypeError);
|
||
|
assertThrows(() => p.setA(4), TypeError);
|
||
|
|
||
|
let x = new Proxy(new C, {});
|
||
|
assertThrows(() => x.getA(), TypeError);
|
||
|
assertThrows(() => x.getA(), TypeError);
|
||
|
assertThrows(() => x.getA(), TypeError);
|
||
|
|
||
|
assertThrows(() => x.setA(2), TypeError);
|
||
|
assertThrows(() => x.setA(3), TypeError);
|
||
|
assertThrows(() => x.setA(4), TypeError);
|
||
|
}
|
||
|
|
||
|
{
|
||
|
class A {
|
||
|
constructor(arg) {
|
||
|
return arg;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class X extends A {
|
||
|
#x = 1;
|
||
|
|
||
|
constructor(arg) {
|
||
|
super(arg);
|
||
|
}
|
||
|
|
||
|
getX(arg) { return arg.#x; }
|
||
|
|
||
|
setX(arg, val) { arg.#x = val; }
|
||
|
}
|
||
|
|
||
|
let proxy = new Proxy({}, {});
|
||
|
let x = new X(proxy);
|
||
|
|
||
|
assertEquals(1, X.prototype.getX(proxy));
|
||
|
assertEquals(1, X.prototype.getX(proxy));
|
||
|
assertEquals(1, X.prototype.getX(proxy));
|
||
|
|
||
|
X.prototype.setX(proxy, 2);
|
||
|
X.prototype.setX(proxy, 3);
|
||
|
X.prototype.setX(proxy, 4);
|
||
|
}
|