%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) {
+ 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;
ObjectFreeze(changeRecord);
ObjectFreeze(changeRecord.removed);
- ObjectInfoEnqueueChangeRecord(objectInfo, changeRecord);
+ ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord);
}
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 = {};
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) {
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) {
notifier.performChange(Thingy.INCREMENT, function() {
self.a += amount;
self.b += amount;
- });
- notifier.notify({
- object: this,
- type: Thingy.INCREMENT,
- incremented: amount
+ return {
+ incremented: amount
+ }; // implicit notify
});
},
notifier.performChange(Thingy.MULTIPLY, function() {
self.a *= amount;
self.b *= amount;
- });
- notifier.notify({
- object: this,
- type: Thingy.MULTIPLY,
- multiplied: amount
+ return {
+ multiplied: amount
+ }; // implicit notify
});
},
notifier.performChange(Thingy.INCREMENT_AND_MULTIPLY, function() {
self.increment(incAmount);
self.multiply(multAmount);
- });
- notifier.notify({
- object: this,
- type: Thingy.INCREMENT_AND_MULTIPLY,
- incremented: incAmount,
- multiplied: multAmount
+ return {
+ incremented: incAmount,
+ multiplied: multAmount
+ }; // implicit notify
});
}
}
});
notifier.notify({
- object: this,
type: RecursiveThingy.MULTIPLY_FIRST_N,
multiplied: amount,
n: n
});
notifier.notify({
- object: this,
type: DeckSuit.SHUFFLE
});
},