Revision: 12983
Author:   [email protected]
Date:     Fri Nov 16 01:35:27 2012
Log: Object.observe: Use [[DefineOwnProperty]] to create properties of changeRecord.

Note: The test here requires https://codereview.chromium.org/11364237/ to land in order to pass because Object.freeze calls Object.getOwnPropertyNames().

BUG=v8:2411

Review URL: https://codereview.chromium.org/11377171
Patch from Rafael Weinstein <[email protected]>.
http://code.google.com/p/v8/source/detail?r=12983

Modified:
 /branches/bleeding_edge/src/object-observe.js
 /branches/bleeding_edge/test/mjsunit/harmony/object-observe.js

=======================================
--- /branches/bleeding_edge/src/object-observe.js       Tue Nov 13 07:53:28 2012
+++ /branches/bleeding_edge/src/object-observe.js       Fri Nov 16 01:35:27 2012
@@ -27,9 +27,6 @@

 "use strict";

-var InternalObjectIsFrozen = $Object.isFrozen;
-var InternalObjectFreeze = $Object.freeze;
-
 var observationState = %GetObservationState();
 if (IS_UNDEFINED(observationState.observerInfoMap)) {
   observationState.observerInfoMap = %CreateObjectHashTable();
@@ -74,7 +71,7 @@
     throw MakeTypeError("observe_non_object", ["observe"]);
   if (!IS_SPEC_FUNCTION(callback))
     throw MakeTypeError("observe_non_function", ["observe"]);
-  if (InternalObjectIsFrozen(callback))
+  if (ObjectIsFrozen(callback))
     throw MakeTypeError("observe_callback_frozen");

   if (!observerInfoMap.has(callback)) {
@@ -134,7 +131,7 @@
   var changeRecord = (arguments.length < 4) ?
       { type: type, object: object, name: name } :
       { type: type, object: object, name: name, oldValue: oldValue };
-  InternalObjectFreeze(changeRecord);
+  ObjectFreeze(changeRecord);
   EnqueueChangeRecord(changeRecord, objectInfo.changeObservers);
 }

@@ -164,9 +161,11 @@
   for (var prop in changeRecord) {
     if (prop === 'object')
       continue;
-    newRecord[prop] = changeRecord[prop];
+
+    %DefineOrRedefineDataProperty(newRecord, prop, changeRecord[prop],
+        READ_ONLY + DONT_DELETE);
   }
-  InternalObjectFreeze(newRecord);
+  ObjectFreeze(newRecord);

   EnqueueChangeRecord(newRecord, objectInfo.changeObservers);
 }
@@ -175,7 +174,7 @@
   if (!IS_SPEC_OBJECT(object))
     throw MakeTypeError("observe_non_object", ["getNotifier"]);

-  if (InternalObjectIsFrozen(object))
+  if (ObjectIsFrozen(object))
     return null;

   var objectInfo = objectInfoMap.get(object);
=======================================
--- /branches/bleeding_edge/test/mjsunit/harmony/object-observe.js Thu Nov 15 03:31:40 2012 +++ /branches/bleeding_edge/test/mjsunit/harmony/object-observe.js Fri Nov 16 01:35:27 2012
@@ -129,8 +129,24 @@
 // Object.deliverChangeRecords
assertThrows(function() { Object.deliverChangeRecords(nonFunction); }, TypeError);

-// Multiple records are delivered.
 Object.observe(obj, observer.callback);
+
+// notify uses to [[CreateOwnProperty]] to create changeRecord;
+reset();
+var protoExpandoAccessed = false;
+Object.defineProperty(Object.prototype, 'protoExpando',
+  {
+    configurable: true,
+    set: function() { protoExpandoAccessed = true; }
+  }
+);
+notifier.notify({ type: 'foo', protoExpando: 'val'});
+assertFalse(protoExpandoAccessed);
+delete Object.prototype.protoExpando;
+Object.deliverChangeRecords(observer.callback);
+
+// Multiple records are delivered.
+reset();
 notifier.notify({
   type: 'updated',
   name: 'foo',

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to