// 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); }