Chromium Code Reviews| Index: src/object-observe.js |
| diff --git a/src/object-observe.js b/src/object-observe.js |
| index 9c7ac3889eb573b04ae6c4612dc5d4791174fda0..9fd611ae8f59eb1d15ad1e04fd05682770cb03a4 100644 |
| --- a/src/object-observe.js |
| +++ b/src/object-observe.js |
| @@ -386,8 +386,28 @@ function ObserverEnqueueIfActive(observer, objectInfo, changeRecord, |
| %SetObserverDeliveryPending(); |
| } |
| -function ObjectInfoEnqueueChangeRecord(objectInfo, changeRecord, |
| - skipAccessCheck) { |
| +function ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, type) { |
| + if (!ObjectInfoHasActiveObservers(objectInfo)) |
| + return; |
| + |
| + var hasType = !IS_UNDEFINED(type); |
| + var newRecord = hasType ? |
| + { object: ObjectInfoGetObject(objectInfo), type: type } : |
| + { object: ObjectInfoGetObject(objectInfo) }; |
| + |
| + for (var prop in changeRecord) { |
|
arv (Not doing code reviews)
2013/10/23 14:48:34
Do we want inherited properties?
Do we want non e
|
| + if (prop === 'object' || (hasType && prop === 'type')) continue; |
| + %DefineOrRedefineDataProperty(newRecord, prop, changeRecord[prop], |
| + READ_ONLY + DONT_DELETE); |
| + } |
| + ObjectFreeze(newRecord); |
| + |
| + ObjectInfoEnqueueInternalChangeRecord(objectInfo, newRecord, |
| + true /* skip access check */); |
| +} |
| + |
| +function ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord, |
| + skipAccessCheck) { |
| // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| if (IS_SYMBOL(changeRecord.name)) return; |
| @@ -435,7 +455,7 @@ function EnqueueSpliceRecord(array, index, removed, addedCount) { |
| ObjectFreeze(changeRecord); |
| ObjectFreeze(changeRecord.removed); |
| - ObjectInfoEnqueueChangeRecord(objectInfo, changeRecord); |
| + ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord); |
| } |
| function NotifyChange(type, object, name, oldValue) { |
| @@ -447,7 +467,7 @@ function NotifyChange(type, object, name, oldValue) { |
| { type: type, object: object, name: name } : |
| { type: type, object: object, name: name, oldValue: oldValue }; |
| ObjectFreeze(changeRecord); |
| - ObjectInfoEnqueueChangeRecord(objectInfo, changeRecord); |
| + ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord); |
| } |
| var notifierPrototype = {}; |
| @@ -462,19 +482,7 @@ function ObjectNotifierNotify(changeRecord) { |
| if (!IS_STRING(changeRecord.type)) |
| throw MakeTypeError("observe_type_non_string"); |
| - if (!ObjectInfoHasActiveObservers(objectInfo)) |
| - return; |
| - |
| - var newRecord = { object: ObjectInfoGetObject(objectInfo) }; |
| - for (var prop in changeRecord) { |
| - if (prop === 'object') continue; |
| - %DefineOrRedefineDataProperty(newRecord, prop, changeRecord[prop], |
| - READ_ONLY + DONT_DELETE); |
| - } |
| - ObjectFreeze(newRecord); |
| - |
| - ObjectInfoEnqueueChangeRecord(objectInfo, newRecord, |
| - true /* skip access check */); |
| + ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord); |
| } |
| function ObjectNotifierPerformChange(changeType, changeFn) { |
| @@ -491,11 +499,16 @@ function ObjectNotifierPerformChange(changeType, changeFn) { |
| throw MakeTypeError("observe_perform_non_function"); |
| ObjectInfoAddPerformingType(objectInfo, changeType); |
| + |
| + var changeRecord; |
| try { |
| - %_CallFunction(UNDEFINED, changeFn); |
| + changeRecord = %_CallFunction(UNDEFINED, changeFn); |
| } finally { |
| ObjectInfoRemovePerformingType(objectInfo, changeType); |
| } |
| + |
| + if (IS_SPEC_OBJECT(changeRecord)) |
| + ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, changeType); |
| } |
| function ObjectGetNotifier(object) { |