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

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

Issue 36313002: [Object.observe] Implement implicit notification from performChange (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: moar Created 7 years, 2 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 | « no previous file | 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 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 } 379 }
380 380
381 var callbackInfo = CallbackInfoNormalize(callback); 381 var callbackInfo = CallbackInfoNormalize(callback);
382 if (!observationState.pendingObservers) 382 if (!observationState.pendingObservers)
383 observationState.pendingObservers = { __proto__: null }; 383 observationState.pendingObservers = { __proto__: null };
384 observationState.pendingObservers[callbackInfo.priority] = callback; 384 observationState.pendingObservers[callbackInfo.priority] = callback;
385 callbackInfo.push(changeRecord); 385 callbackInfo.push(changeRecord);
386 %SetObserverDeliveryPending(); 386 %SetObserverDeliveryPending();
387 } 387 }
388 388
389 function ObjectInfoEnqueueChangeRecord(objectInfo, changeRecord, 389 function ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, type) {
390 skipAccessCheck) { 390 if (!ObjectInfoHasActiveObservers(objectInfo))
391 return;
392
393 var hasType = !IS_UNDEFINED(type);
394 var newRecord = hasType ?
395 { object: ObjectInfoGetObject(objectInfo), type: type } :
396 { object: ObjectInfoGetObject(objectInfo) };
397
398 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
399 if (prop === 'object' || (hasType && prop === 'type')) continue;
400 %DefineOrRedefineDataProperty(newRecord, prop, changeRecord[prop],
401 READ_ONLY + DONT_DELETE);
402 }
403 ObjectFreeze(newRecord);
404
405 ObjectInfoEnqueueInternalChangeRecord(objectInfo, newRecord,
406 true /* skip access check */);
407 }
408
409 function ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord,
410 skipAccessCheck) {
391 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 411 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
392 if (IS_SYMBOL(changeRecord.name)) return; 412 if (IS_SYMBOL(changeRecord.name)) return;
393 413
394 var needsAccessCheck = !skipAccessCheck && 414 var needsAccessCheck = !skipAccessCheck &&
395 %IsAccessCheckNeeded(changeRecord.object); 415 %IsAccessCheckNeeded(changeRecord.object);
396 416
397 if (ChangeObserversIsOptimized(objectInfo.changeObservers)) { 417 if (ChangeObserversIsOptimized(objectInfo.changeObservers)) {
398 var observer = objectInfo.changeObservers; 418 var observer = objectInfo.changeObservers;
399 ObserverEnqueueIfActive(observer, objectInfo, changeRecord, 419 ObserverEnqueueIfActive(observer, objectInfo, changeRecord,
400 needsAccessCheck); 420 needsAccessCheck);
(...skipping 27 matching lines...) Expand all
428 var changeRecord = { 448 var changeRecord = {
429 type: 'splice', 449 type: 'splice',
430 object: array, 450 object: array,
431 index: index, 451 index: index,
432 removed: removed, 452 removed: removed,
433 addedCount: addedCount 453 addedCount: addedCount
434 }; 454 };
435 455
436 ObjectFreeze(changeRecord); 456 ObjectFreeze(changeRecord);
437 ObjectFreeze(changeRecord.removed); 457 ObjectFreeze(changeRecord.removed);
438 ObjectInfoEnqueueChangeRecord(objectInfo, changeRecord); 458 ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord);
439 } 459 }
440 460
441 function NotifyChange(type, object, name, oldValue) { 461 function NotifyChange(type, object, name, oldValue) {
442 var objectInfo = objectInfoMap.get(object); 462 var objectInfo = objectInfoMap.get(object);
443 if (!ObjectInfoHasActiveObservers(objectInfo)) 463 if (!ObjectInfoHasActiveObservers(objectInfo))
444 return; 464 return;
445 465
446 var changeRecord = (arguments.length < 4) ? 466 var changeRecord = (arguments.length < 4) ?
447 { type: type, object: object, name: name } : 467 { type: type, object: object, name: name } :
448 { type: type, object: object, name: name, oldValue: oldValue }; 468 { type: type, object: object, name: name, oldValue: oldValue };
449 ObjectFreeze(changeRecord); 469 ObjectFreeze(changeRecord);
450 ObjectInfoEnqueueChangeRecord(objectInfo, changeRecord); 470 ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord);
451 } 471 }
452 472
453 var notifierPrototype = {}; 473 var notifierPrototype = {};
454 474
455 function ObjectNotifierNotify(changeRecord) { 475 function ObjectNotifierNotify(changeRecord) {
456 if (!IS_SPEC_OBJECT(this)) 476 if (!IS_SPEC_OBJECT(this))
457 throw MakeTypeError("called_on_non_object", ["notify"]); 477 throw MakeTypeError("called_on_non_object", ["notify"]);
458 478
459 var objectInfo = ObjectInfoGetFromNotifier(this); 479 var objectInfo = ObjectInfoGetFromNotifier(this);
460 if (IS_UNDEFINED(objectInfo)) 480 if (IS_UNDEFINED(objectInfo))
461 throw MakeTypeError("observe_notify_non_notifier"); 481 throw MakeTypeError("observe_notify_non_notifier");
462 if (!IS_STRING(changeRecord.type)) 482 if (!IS_STRING(changeRecord.type))
463 throw MakeTypeError("observe_type_non_string"); 483 throw MakeTypeError("observe_type_non_string");
464 484
465 if (!ObjectInfoHasActiveObservers(objectInfo)) 485 ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord);
466 return;
467
468 var newRecord = { object: ObjectInfoGetObject(objectInfo) };
469 for (var prop in changeRecord) {
470 if (prop === 'object') continue;
471 %DefineOrRedefineDataProperty(newRecord, prop, changeRecord[prop],
472 READ_ONLY + DONT_DELETE);
473 }
474 ObjectFreeze(newRecord);
475
476 ObjectInfoEnqueueChangeRecord(objectInfo, newRecord,
477 true /* skip access check */);
478 } 486 }
479 487
480 function ObjectNotifierPerformChange(changeType, changeFn) { 488 function ObjectNotifierPerformChange(changeType, changeFn) {
481 if (!IS_SPEC_OBJECT(this)) 489 if (!IS_SPEC_OBJECT(this))
482 throw MakeTypeError("called_on_non_object", ["performChange"]); 490 throw MakeTypeError("called_on_non_object", ["performChange"]);
483 491
484 var objectInfo = ObjectInfoGetFromNotifier(this); 492 var objectInfo = ObjectInfoGetFromNotifier(this);
485 493
486 if (IS_UNDEFINED(objectInfo)) 494 if (IS_UNDEFINED(objectInfo))
487 throw MakeTypeError("observe_notify_non_notifier"); 495 throw MakeTypeError("observe_notify_non_notifier");
488 if (!IS_STRING(changeType)) 496 if (!IS_STRING(changeType))
489 throw MakeTypeError("observe_perform_non_string"); 497 throw MakeTypeError("observe_perform_non_string");
490 if (!IS_SPEC_FUNCTION(changeFn)) 498 if (!IS_SPEC_FUNCTION(changeFn))
491 throw MakeTypeError("observe_perform_non_function"); 499 throw MakeTypeError("observe_perform_non_function");
492 500
493 ObjectInfoAddPerformingType(objectInfo, changeType); 501 ObjectInfoAddPerformingType(objectInfo, changeType);
502
503 var changeRecord;
494 try { 504 try {
495 %_CallFunction(UNDEFINED, changeFn); 505 changeRecord = %_CallFunction(UNDEFINED, changeFn);
496 } finally { 506 } finally {
497 ObjectInfoRemovePerformingType(objectInfo, changeType); 507 ObjectInfoRemovePerformingType(objectInfo, changeType);
498 } 508 }
509
510 if (IS_SPEC_OBJECT(changeRecord))
511 ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, changeType);
499 } 512 }
500 513
501 function ObjectGetNotifier(object) { 514 function ObjectGetNotifier(object) {
502 if (!IS_SPEC_OBJECT(object)) 515 if (!IS_SPEC_OBJECT(object))
503 throw MakeTypeError("observe_non_object", ["getNotifier"]); 516 throw MakeTypeError("observe_non_object", ["getNotifier"]);
504 517
505 if (ObjectIsFrozen(object)) return null; 518 if (ObjectIsFrozen(object)) return null;
506 519
507 var objectInfo = ObjectInfoGet(object); 520 var objectInfo = ObjectInfoGet(object);
508 return ObjectInfoGetNotifier(objectInfo); 521 return ObjectInfoGetNotifier(objectInfo);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 "observe", ArrayObserve, 572 "observe", ArrayObserve,
560 "unobserve", ArrayUnobserve 573 "unobserve", ArrayUnobserve
561 )); 574 ));
562 InstallFunctions(notifierPrototype, DONT_ENUM, $Array( 575 InstallFunctions(notifierPrototype, DONT_ENUM, $Array(
563 "notify", ObjectNotifierNotify, 576 "notify", ObjectNotifierNotify,
564 "performChange", ObjectNotifierPerformChange 577 "performChange", ObjectNotifierPerformChange
565 )); 578 ));
566 } 579 }
567 580
568 SetupObjectObserve(); 581 SetupObjectObserve();
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/harmony/object-observe.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698