v8/test/mjsunit/harmony/private-fields-ic.js
Sathya Gunasekaran f3cfe09549 [class] Throw on private field access miss
Private fields should not return undefined on access miss, but instead
should throw a TypeError.

This patch uses a bit on v8::Symbol to mark if this symbol is a
private field or not.

This patch also changes the LookupIterator code path that deals with
LookupIterator::State::DATA to deal with JSReceiver instead of
JSObject.

Note: the error message doesn't output the field name, but that's a
WIP.

Bug: v8:5368
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng
Change-Id: I8ae960b478eb6ae1ebf9bc90658ce3654d687977
Reviewed-on: https://chromium-review.googlesource.com/905627
Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: Mythri Alle <mythria@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51452}
2018-02-22 01:43:13 +00:00

295 lines
5.8 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.
// Flags: --harmony-private-fields
{
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);
}