Reviewers: rossberg,
Description:
[Object.observe] Implement implicit notification from performChange
R=rossberg
BUG=v8:2942
Please review this at https://codereview.chromium.org/36313002/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+41, -36 lines):
M src/object-observe.js
M test/mjsunit/harmony/object-observe.js
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) {
+ 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) {
Index: test/mjsunit/harmony/object-observe.js
diff --git a/test/mjsunit/harmony/object-observe.js
b/test/mjsunit/harmony/object-observe.js
index
f94ab75e9a84d2cf0d819510782b23a660057bcc..5615d9e3fd1127696bc772c27baed714292116f1
100644
--- a/test/mjsunit/harmony/object-observe.js
+++ b/test/mjsunit/harmony/object-observe.js
@@ -434,12 +434,10 @@ Thingy.prototype = {
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
});
},
@@ -450,12 +448,10 @@ Thingy.prototype = {
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
});
},
@@ -466,13 +462,11 @@ Thingy.prototype = {
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
});
}
}
@@ -545,7 +539,6 @@ RecursiveThingy.prototype = {
});
notifier.notify({
- object: this,
type: RecursiveThingy.MULTIPLY_FIRST_N,
multiplied: amount,
n: n
@@ -606,7 +599,6 @@ DeckSuit.prototype = {
});
notifier.notify({
- object: this,
type: DeckSuit.SHUFFLE
});
},
--
--
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.