Reviewers: rossberg,

Description:
Fix hidden properties on object with frozen prototype.

This fixes a corner-case where a frozen prototype with existing hidden
properties might prevent setting hidden properties on another object.

[email protected]
BUG=v8:2829

Please review this at https://codereview.chromium.org/22799021/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/objects.h
  M src/objects.cc
  A + test/mjsunit/regress/regress-2829.js


Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 7e15f3005d6cbb035c4d9818eab72cefdc58617d..5960e9ef82045b2d72ad51e1781a0935c2dc83c3 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -2151,7 +2151,6 @@ MaybeObject* JSObject::SetPropertyPostInterceptor(
     Object* value,
     PropertyAttributes attributes,
     StrictModeFlag strict_mode,
-    ExtensibilityCheck extensibility_check,
     StoreMode mode) {
   // Check local property, ignore interceptor.
   LookupResult result(GetIsolate());
@@ -2163,13 +2162,12 @@ MaybeObject* JSObject::SetPropertyPostInterceptor(
     return SetProperty(&result, name, value, attributes, strict_mode);
   }
   bool done = false;
-  MaybeObject* result_object;
-  result_object =
+  MaybeObject* result_object =
SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done);
   if (done) return result_object;
   // Add a new real property.
   return AddProperty(name, value, attributes, strict_mode,
-                     MAY_BE_STORE_FROM_KEYED, extensibility_check,
+                     MAY_BE_STORE_FROM_KEYED, PERFORM_EXTENSIBILITY_CHECK,
                      OPTIMAL_REPRESENTATION, mode);
 }

@@ -2827,8 +2825,7 @@ MaybeObject* JSObject::SetPropertyWithInterceptor(
       this_handle->SetPropertyPostInterceptor(*name_handle,
                                               *value_handle,
                                               attributes,
-                                              strict_mode,
-                                              PERFORM_EXTENSIBILITY_CHECK);
+                                              strict_mode);
   RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   return raw_result;
 }
@@ -4027,7 +4024,8 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
     Object* value_raw,
     PropertyAttributes attributes,
     ValueType value_type,
-    StoreMode mode) {
+    StoreMode mode,
+    ExtensibilityCheck extensibility_check) {
   // Make sure that the top context does not change when doing callbacks or
   // interceptor calls.
   AssertNoContextChange ncc;
@@ -4055,7 +4053,8 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
         value_raw,
         attributes,
         value_type,
-        mode);
+        mode,
+        extensibility_check);
   }

   // Check for accessor in prototype chain removed here in clone.
@@ -4063,7 +4062,7 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
     // Neither properties nor transitions found.
     return AddProperty(
         name_raw, value_raw, attributes, kNonStrictMode,
- MAY_BE_STORE_FROM_KEYED, PERFORM_EXTENSIBILITY_CHECK, value_type, mode);
+        MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode);
   }

   // From this point on everything needs to be handlified.
@@ -4983,12 +4982,12 @@ MaybeObject* JSObject::GetHiddenPropertiesHashTable(
   }

   MaybeObject* store_result =
-      SetPropertyPostInterceptor(GetHeap()->hidden_string(),
-                                 hashtable,
-                                 DONT_ENUM,
-                                 kNonStrictMode,
-                                 OMIT_EXTENSIBILITY_CHECK,
-                                 FORCE_FIELD);
+      SetLocalPropertyIgnoreAttributes(GetHeap()->hidden_string(),
+                                       hashtable,
+                                       DONT_ENUM,
+                                       OPTIMAL_REPRESENTATION,
+                                       ALLOW_AS_CONSTANT,
+                                       OMIT_EXTENSIBILITY_CHECK);
   if (store_result->IsFailure()) return store_result;
   return hashtable;
 }
@@ -5016,12 +5015,12 @@ MaybeObject* JSObject::SetHiddenPropertiesHashTable(Object* value) {
     }
   }
   MaybeObject* store_result =
-      SetPropertyPostInterceptor(GetHeap()->hidden_string(),
-                                 value,
-                                 DONT_ENUM,
-                                 kNonStrictMode,
-                                 OMIT_EXTENSIBILITY_CHECK,
-                                 FORCE_FIELD);
+      SetLocalPropertyIgnoreAttributes(GetHeap()->hidden_string(),
+                                       value,
+                                       DONT_ENUM,
+                                       OPTIMAL_REPRESENTATION,
+                                       ALLOW_AS_CONSTANT,
+                                       OMIT_EXTENSIBILITY_CHECK);
   if (store_result->IsFailure()) return store_result;
   return this;
 }
@@ -15363,6 +15362,7 @@ MaybeObject* ObjectHashSet::Add(Object* key) {
   int hash;
   { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION);
     if (maybe_hash->IsFailure()) return maybe_hash;
+    ASSERT(key->GetHash(OMIT_CREATION) == maybe_hash);
     hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value();
   }
   int entry = FindEntry(key);
@@ -15424,6 +15424,7 @@ MaybeObject* ObjectHashTable::Put(Object* key, Object* value) {
   int hash;
   { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION);
     if (maybe_hash->IsFailure()) return maybe_hash;
+    ASSERT(key->GetHash(OMIT_CREATION) == maybe_hash);
     hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value();
   }
   int entry = FindEntry(key);
Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index 96b4011664bef5255601b653a0a664e1a7367551..9eafce3a261b8e267da14193cd22f88c2340f19b 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -2159,7 +2159,6 @@ class JSObject: public JSReceiver {
       Object* value,
       PropertyAttributes attributes,
       StrictModeFlag strict_mode,
-      ExtensibilityCheck extensibility_check,
       StoreMode mode = ALLOW_AS_CONSTANT);

   static Handle<Object> SetLocalPropertyIgnoreAttributes(
@@ -2197,7 +2196,8 @@ class JSObject: public JSReceiver {
       Object* value,
       PropertyAttributes attributes,
       ValueType value_type = OPTIMAL_REPRESENTATION,
-      StoreMode mode = ALLOW_AS_CONSTANT);
+      StoreMode mode = ALLOW_AS_CONSTANT,
+ ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK);

   // Retrieve a value in a normalized object given a lookup result.
   // Handles the special representation of JS global objects.
Index: test/mjsunit/regress/regress-2829.js
diff --git a/test/mjsunit/regress/regress-2717.js b/test/mjsunit/regress/regress-2829.js
similarity index 75%
copy from test/mjsunit/regress/regress-2717.js
copy to test/mjsunit/regress/regress-2829.js
index 4f8f7915b1c43e48235e7bd6bcb79f89957223cf..a046ae0395af59fb8f85bf762d1b43ef3e355405 100644
--- a/test/mjsunit/regress/regress-2717.js
+++ b/test/mjsunit/regress/regress-2829.js
@@ -25,27 +25,29 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

-// Test re-initializing existing field which is already being tracked as
-// having double representation.
-(function() {
-  function test1(a) {
-    return { x: 1.5, x: a };
-  };
+// Flags: --harmony-collections

-  assertEquals({}, test1({}).x);
-})();
+(function test1() {
+  var wm1 = new WeakMap();
+  wm1.set(Object.prototype, 23);
+  assertTrue(wm1.has(Object.prototype));
+  Object.freeze(Object.prototype);

-// Test initializing new field which follows an existing transition to a
-// map that tracks it as having double representation.
-(function() {
-  function test1(a) {
-    return { y: a };
-  };
+  var wm2 = new WeakMap();
+  var o = {};
+  wm2.set(o, 42);
+  assertEquals(42, wm2.get(o));
+})();

-  function test2(a) {
-    return { y: a };
-  };
+(function test2() {
+  var wm1 = new WeakMap();
+  var o1 = {};
+  wm1.set(o1, 23);
+  assertTrue(wm1.has(o1));
+  Object.freeze(o1);

-  assertEquals(1.5, test1(1.5).y);
-  assertEquals({}, test2({}).y);
+  var wm2 = new WeakMap();
+  var o2 = Object.create(o1);
+  wm2.set(o2, 42);
+  assertEquals(42, wm2.get(o2));
 })();


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to