Make freeze & friends ignore private properties

R=verwaest@chromium.org
BUG=v8:3419
LOG=Y

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22132 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
rossberg@chromium.org 2014-07-01 15:47:41 +00:00
parent 0941f24566
commit 8a25b88722
3 changed files with 30 additions and 11 deletions

View File

@ -5679,7 +5679,8 @@ static void FreezeDictionary(Dictionary* dictionary) {
int capacity = dictionary->Capacity();
for (int i = 0; i < capacity; i++) {
Object* k = dictionary->KeyAt(i);
if (dictionary->IsKey(k)) {
if (dictionary->IsKey(k) &&
!(k->IsSymbol() && Symbol::cast(k)->is_private())) {
PropertyDetails details = dictionary->DetailsAt(i);
int attrs = DONT_DELETE;
// READ_ONLY is an invalid attribute for JS setters/getters.
@ -7453,17 +7454,20 @@ Handle<DescriptorArray> DescriptorArray::CopyUpToAddAttributes(
if (attributes != NONE) {
for (int i = 0; i < size; ++i) {
Object* value = desc->GetValue(i);
Name* key = desc->GetKey(i);
PropertyDetails details = desc->GetDetails(i);
int mask = DONT_DELETE | DONT_ENUM;
// READ_ONLY is an invalid attribute for JS setters/getters.
if (details.type() != CALLBACKS || !value->IsAccessorPair()) {
mask |= READ_ONLY;
// Bulk attribute changes never affect private properties.
if (!key->IsSymbol() || !Symbol::cast(key)->is_private()) {
int mask = DONT_DELETE | DONT_ENUM;
// READ_ONLY is an invalid attribute for JS setters/getters.
if (details.type() != CALLBACKS || !value->IsAccessorPair()) {
mask |= READ_ONLY;
}
details = details.CopyAddAttributes(
static_cast<PropertyAttributes>(attributes & mask));
}
details = details.CopyAddAttributes(
static_cast<PropertyAttributes>(attributes & mask));
Descriptor inner_desc(handle(desc->GetKey(i)),
handle(value, desc->GetIsolate()),
details);
Descriptor inner_desc(
handle(key), handle(value, desc->GetIsolate()), details);
descriptors->Set(i, &inner_desc, witness);
}
} else {

View File

@ -180,7 +180,7 @@ class Types {
NumberFunction2 = Type::Function(Number, Number, Number, region);
MethodFunction = Type::Function(String, Object, 0, region);
for (int i = 0; i < 50; ++i) {
for (int i = 0; i < 40; ++i) {
types.push_back(Fuzz());
}
}

View File

@ -342,3 +342,18 @@ function TestGetOwnPropertySymbols() {
assertEquals(syms, [publicSymbol, publicSymbol2])
}
TestGetOwnPropertySymbols()
function TestSealAndFreeze(freeze) {
var sym = %CreatePrivateSymbol("private")
var obj = {}
obj[sym] = 1
freeze(obj)
obj[sym] = 2
assertEquals(2, obj[sym])
assertTrue(delete obj[sym])
assertEquals(undefined, obj[sym])
}
TestSealAndFreeze(Object.seal)
TestSealAndFreeze(Object.freeze)
TestSealAndFreeze(Object.preventExtensions)