Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(172)

Side by Side Diff: src/object-observe.js

Issue 14978007: Implement Array.observe and emit splice change records for ArrayPush (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: todo to freeze removed Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/array.js ('k') | test/mjsunit/harmony/object-observe.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 159
160 function EndPerformChange(objectInfo, type) { 160 function EndPerformChange(objectInfo, type) {
161 objectInfo.performing[type]--; 161 objectInfo.performing[type]--;
162 objectInfo.performingCount--; 162 objectInfo.performingCount--;
163 RepartitionObservers(ObserverIsActive, 163 RepartitionObservers(ObserverIsActive,
164 objectInfo.inactiveObservers, 164 objectInfo.inactiveObservers,
165 objectInfo.changeObservers, 165 objectInfo.changeObservers,
166 objectInfo); 166 objectInfo);
167 } 167 }
168 168
169 function ensureObserverRemoved(objectInfo, callback) { 169 function EnsureObserverRemoved(objectInfo, callback) {
170 function remove(observerList) { 170 function remove(observerList) {
171 for (var i = 0; i < observerList.length; i++) { 171 for (var i = 0; i < observerList.length; i++) {
172 if (observerList[i].callback === callback) { 172 if (observerList[i].callback === callback) {
173 observerList.splice(i, 1); 173 observerList.splice(i, 1);
174 return true; 174 return true;
175 } 175 }
176 } 176 }
177 return false; 177 return false;
178 } 178 }
179 179
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 observerInfoMap.set(callback, { 212 observerInfoMap.set(callback, {
213 pendingChangeRecords: null, 213 pendingChangeRecords: null,
214 priority: observationState.observerPriority++, 214 priority: observationState.observerPriority++,
215 }); 215 });
216 } 216 }
217 217
218 var objectInfo = objectInfoMap.get(object); 218 var objectInfo = objectInfoMap.get(object);
219 if (IS_UNDEFINED(objectInfo)) objectInfo = CreateObjectInfo(object); 219 if (IS_UNDEFINED(objectInfo)) objectInfo = CreateObjectInfo(object);
220 %SetIsObserved(object, true); 220 %SetIsObserved(object, true);
221 221
222 ensureObserverRemoved(objectInfo, callback); 222 EnsureObserverRemoved(objectInfo, callback);
223 223
224 var observer = CreateObserver(callback, accept); 224 var observer = CreateObserver(callback, accept);
225 if (ObserverIsActive(observer, objectInfo)) 225 if (ObserverIsActive(observer, objectInfo))
226 objectInfo.changeObservers.push(observer); 226 objectInfo.changeObservers.push(observer);
227 else 227 else
228 objectInfo.inactiveObservers.push(observer); 228 objectInfo.inactiveObservers.push(observer);
229 229
230 return object; 230 return object;
231 } 231 }
232 232
233 function ObjectUnobserve(object, callback) { 233 function ObjectUnobserve(object, callback) {
234 if (!IS_SPEC_OBJECT(object)) 234 if (!IS_SPEC_OBJECT(object))
235 throw MakeTypeError("observe_non_object", ["unobserve"]); 235 throw MakeTypeError("observe_non_object", ["unobserve"]);
236 if (!IS_SPEC_FUNCTION(callback)) 236 if (!IS_SPEC_FUNCTION(callback))
237 throw MakeTypeError("observe_non_function", ["unobserve"]); 237 throw MakeTypeError("observe_non_function", ["unobserve"]);
238 238
239 var objectInfo = objectInfoMap.get(object); 239 var objectInfo = objectInfoMap.get(object);
240 if (IS_UNDEFINED(objectInfo)) 240 if (IS_UNDEFINED(objectInfo))
241 return object; 241 return object;
242 242
243 ensureObserverRemoved(objectInfo, callback); 243 EnsureObserverRemoved(objectInfo, callback);
244 244
245 if (objectInfo.changeObservers.length === 0 && 245 if (objectInfo.changeObservers.length === 0 &&
246 objectInfo.inactiveObservers.length === 0) { 246 objectInfo.inactiveObservers.length === 0) {
247 %SetIsObserved(object, false); 247 %SetIsObserved(object, false);
248 } 248 }
249 249
250 return object; 250 return object;
251 } 251 }
252 252
253 function ArrayObserve(object, callback) {
254 return ObjectObserve(object, callback, ['new',
255 'updated',
256 'deleted',
257 'splice']);
258 }
259
260 function ArrayUnobserve(object, callback) {
261 return ObjectUnobserve(object, callback);
262 }
263
253 function EnqueueChangeRecord(changeRecord, observers) { 264 function EnqueueChangeRecord(changeRecord, observers) {
254 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 265 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
255 if (IS_SYMBOL(changeRecord.name)) return; 266 if (IS_SYMBOL(changeRecord.name)) return;
256 267
257 for (var i = 0; i < observers.length; i++) { 268 for (var i = 0; i < observers.length; i++) {
258 var observer = observers[i]; 269 var observer = observers[i];
259 if (IS_UNDEFINED(observer.accept[changeRecord.type])) 270 if (IS_UNDEFINED(observer.accept[changeRecord.type]))
260 continue; 271 continue;
261 272
262 var callback = observer.callback; 273 var callback = observer.callback;
263 var observerInfo = observerInfoMap.get(callback); 274 var observerInfo = observerInfoMap.get(callback);
264 observationState.pendingObservers[observerInfo.priority] = callback; 275 observationState.pendingObservers[observerInfo.priority] = callback;
265 %SetObserverDeliveryPending(); 276 %SetObserverDeliveryPending();
266 if (IS_NULL(observerInfo.pendingChangeRecords)) { 277 if (IS_NULL(observerInfo.pendingChangeRecords)) {
267 observerInfo.pendingChangeRecords = new InternalArray(changeRecord); 278 observerInfo.pendingChangeRecords = new InternalArray(changeRecord);
268 } else { 279 } else {
269 observerInfo.pendingChangeRecords.push(changeRecord); 280 observerInfo.pendingChangeRecords.push(changeRecord);
270 } 281 }
271 } 282 }
272 } 283 }
273 284
285 function BeginPerformSplice(array) {
286 var objectInfo = objectInfoMap.get(array);
287 if (!IS_UNDEFINED(objectInfo))
288 BeginPerformChange(objectInfo, 'splice');
289 }
290
291 function EndPerformSplice(array) {
292 var objectInfo = objectInfoMap.get(array);
293 if (!IS_UNDEFINED(objectInfo))
294 EndPerformChange(objectInfo, 'splice');
295 }
296
297 function EnqueueSpliceRecord(array, index, removed, deleteCount, addedCount) {
298 var objectInfo = objectInfoMap.get(array);
299 if (IS_UNDEFINED(objectInfo) || objectInfo.changeObservers.length === 0)
300 return;
301
302 var changeRecord = {
303 type: 'splice',
304 object: array,
305 index: index,
306 removed: removed,
307 addedCount: addedCount
308 };
309
310 changeRecord.removed.length = deleteCount;
311 // TODO(rafaelw): This breaks spec-compliance. Re-enable when freezing isn't
312 // slow.
313 // ObjectFreeze(changeRecord);
314 // ObjectFreeze(changeRecord.removed);
315 EnqueueChangeRecord(changeRecord, objectInfo.changeObservers);
316 }
317
274 function NotifyChange(type, object, name, oldValue) { 318 function NotifyChange(type, object, name, oldValue) {
275 var objectInfo = objectInfoMap.get(object); 319 var objectInfo = objectInfoMap.get(object);
276 if (objectInfo.changeObservers.length === 0) 320 if (objectInfo.changeObservers.length === 0)
277 return; 321 return;
278 322
279 var changeRecord = (arguments.length < 4) ? 323 var changeRecord = (arguments.length < 4) ?
280 { type: type, object: object, name: name } : 324 { type: type, object: object, name: name } :
281 { type: type, object: object, name: name, oldValue: oldValue }; 325 { type: type, object: object, name: name, oldValue: oldValue };
282 // TODO(rafaelw): This breaks spec-compliance. Re-enable when freezing isn't 326 // TODO(rafaelw): This breaks spec-compliance. Re-enable when freezing isn't
283 // slow. 327 // slow.
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 } 442 }
399 443
400 function SetupObjectObserve() { 444 function SetupObjectObserve() {
401 %CheckIsBootstrapping(); 445 %CheckIsBootstrapping();
402 InstallFunctions($Object, DONT_ENUM, $Array( 446 InstallFunctions($Object, DONT_ENUM, $Array(
403 "deliverChangeRecords", ObjectDeliverChangeRecords, 447 "deliverChangeRecords", ObjectDeliverChangeRecords,
404 "getNotifier", ObjectGetNotifier, 448 "getNotifier", ObjectGetNotifier,
405 "observe", ObjectObserve, 449 "observe", ObjectObserve,
406 "unobserve", ObjectUnobserve 450 "unobserve", ObjectUnobserve
407 )); 451 ));
452 InstallFunctions($Array, DONT_ENUM, $Array(
453 "observe", ArrayObserve,
454 "unobserve", ArrayUnobserve
455 ));
408 InstallFunctions(notifierPrototype, DONT_ENUM, $Array( 456 InstallFunctions(notifierPrototype, DONT_ENUM, $Array(
409 "notify", ObjectNotifierNotify, 457 "notify", ObjectNotifierNotify,
410 "performChange", ObjectNotifierPerformChange 458 "performChange", ObjectNotifierPerformChange
411 )); 459 ));
412 } 460 }
413 461
414 SetupObjectObserve(); 462 SetupObjectObserve();
OLDNEW
« no previous file with comments | « src/array.js ('k') | test/mjsunit/harmony/object-observe.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698