From 8a25b887222f932e765e95e38c902ec8caca271b Mon Sep 17 00:00:00 2001 From: "rossberg@chromium.org" Date: Tue, 1 Jul 2014 15:47:41 +0000 Subject: [PATCH] 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 --- src/objects.cc | 24 ++++++++++++++---------- test/cctest/test-types.cc | 2 +- test/mjsunit/harmony/private.js | 15 +++++++++++++++ 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/objects.cc b/src/objects.cc index 785bd4c..7db464e 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -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::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(attributes & mask)); } - details = details.CopyAddAttributes( - static_cast(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 { diff --git a/test/cctest/test-types.cc b/test/cctest/test-types.cc index 3aeadaa..7be18c5 100644 --- a/test/cctest/test-types.cc +++ b/test/cctest/test-types.cc @@ -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()); } } diff --git a/test/mjsunit/harmony/private.js b/test/mjsunit/harmony/private.js index 2257998..c4b0ed2 100644 --- a/test/mjsunit/harmony/private.js +++ b/test/mjsunit/harmony/private.js @@ -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) -- 2.7.4