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 <rafaelw@chromium.org>. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12983 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
af824eab8f
commit
2e76922c79
@ -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 @@ function ObjectObserve(object, callback) {
|
||||
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 @@ function NotifyChange(type, object, name, oldValue) {
|
||||
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 @@ function ObjectNotifierNotify(changeRecord) {
|
||||
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 @@ function ObjectGetNotifier(object) {
|
||||
if (!IS_SPEC_OBJECT(object))
|
||||
throw MakeTypeError("observe_non_object", ["getNotifier"]);
|
||||
|
||||
if (InternalObjectIsFrozen(object))
|
||||
if (ObjectIsFrozen(object))
|
||||
return null;
|
||||
|
||||
var objectInfo = objectInfoMap.get(object);
|
||||
|
@ -129,8 +129,24 @@ assertFalse(recordCreated); // not observed yet
|
||||
// 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',
|
||||
|
Loading…
Reference in New Issue
Block a user