Make freeze & friends ignore private properties
authorrossberg@chromium.org <rossberg@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 1 Jul 2014 15:47:41 +0000 (15:47 +0000)
committerrossberg@chromium.org <rossberg@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 1 Jul 2014 15:47:41 +0000 (15:47 +0000)
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
test/cctest/test-types.cc
test/mjsunit/harmony/private.js

index 785bd4c..7db464e 100644 (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 {
index 3aeadaa..7be18c5 100644 (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());
     }
   }
index 2257998..c4b0ed2 100644 (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)