| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 var $observeNotifyChange; | 5 var $observeNotifyChange; | 
| 6 var $observeEnqueueSpliceRecord; | 6 var $observeEnqueueSpliceRecord; | 
| 7 var $observeBeginPerformSplice; | 7 var $observeBeginPerformSplice; | 
| 8 var $observeEndPerformSplice; | 8 var $observeEndPerformSplice; | 
| 9 var $observeNativeObjectObserve; | 9 var $observeNativeObjectObserve; | 
| 10 var $observeNativeObjectGetNotifier; | 10 var $observeNativeObjectGetNotifier; | 
| 11 var $observeNativeObjectNotifierPerformChange; | 11 var $observeNativeObjectNotifierPerformChange; | 
| 12 | 12 | 
| 13 (function(global, utils) { | 13 (function(global, utils) { | 
| 14 | 14 | 
| 15 "use strict"; | 15 "use strict"; | 
| 16 | 16 | 
| 17 %CheckIsBootstrapping(); | 17 %CheckIsBootstrapping(); | 
| 18 | 18 | 
| 19 // ------------------------------------------------------------------- | 19 // ------------------------------------------------------------------- | 
| 20 // Imports | 20 // Imports | 
| 21 | 21 | 
| 22 var GlobalArray = global.Array; | 22 var GlobalArray = global.Array; | 
| 23 var GlobalObject = global.Object; | 23 var GlobalObject = global.Object; | 
| 24 var InternalArray = utils.InternalArray; | 24 var InternalArray = utils.InternalArray; | 
| 25 | 25 | 
|  | 26 var ObjectFreeze; | 
|  | 27 var ObjectIsFrozen; | 
|  | 28 | 
|  | 29 utils.Import(function(from) { | 
|  | 30   ObjectFreeze = from.ObjectFreeze; | 
|  | 31   ObjectIsFrozen = from.ObjectIsFrozen; | 
|  | 32 }); | 
|  | 33 | 
| 26 // ------------------------------------------------------------------- | 34 // ------------------------------------------------------------------- | 
| 27 | 35 | 
| 28 // Overview: | 36 // Overview: | 
| 29 // | 37 // | 
| 30 // This file contains all of the routing and accounting for Object.observe. | 38 // This file contains all of the routing and accounting for Object.observe. | 
| 31 // User code will interact with these mechanisms via the Object.observe APIs | 39 // User code will interact with these mechanisms via the Object.observe APIs | 
| 32 // and, as a side effect of mutation objects which are observed. The V8 runtime | 40 // and, as a side effect of mutation objects which are observed. The V8 runtime | 
| 33 // (both C++ and JS) will interact with these mechanisms primarily by enqueuing | 41 // (both C++ and JS) will interact with these mechanisms primarily by enqueuing | 
| 34 // proper change records for objects which were mutated. The Object.observe | 42 // proper change records for objects which were mutated. The Object.observe | 
| 35 // routing and accounting consists primarily of three participants | 43 // routing and accounting consists primarily of three participants | 
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 373 } | 381 } | 
| 374 | 382 | 
| 375 | 383 | 
| 376 function ObjectObserve(object, callback, acceptList) { | 384 function ObjectObserve(object, callback, acceptList) { | 
| 377   if (!IS_SPEC_OBJECT(object)) | 385   if (!IS_SPEC_OBJECT(object)) | 
| 378     throw MakeTypeError(kObserveNonObject, "observe", "observe"); | 386     throw MakeTypeError(kObserveNonObject, "observe", "observe"); | 
| 379   if (%IsJSGlobalProxy(object)) | 387   if (%IsJSGlobalProxy(object)) | 
| 380     throw MakeTypeError(kObserveGlobalProxy, "observe"); | 388     throw MakeTypeError(kObserveGlobalProxy, "observe"); | 
| 381   if (!IS_SPEC_FUNCTION(callback)) | 389   if (!IS_SPEC_FUNCTION(callback)) | 
| 382     throw MakeTypeError(kObserveNonFunction, "observe"); | 390     throw MakeTypeError(kObserveNonFunction, "observe"); | 
| 383   if ($objectIsFrozen(callback)) | 391   if (ObjectIsFrozen(callback)) | 
| 384     throw MakeTypeError(kObserveCallbackFrozen); | 392     throw MakeTypeError(kObserveCallbackFrozen); | 
| 385 | 393 | 
| 386   var objectObserveFn = %GetObjectContextObjectObserve(object); | 394   var objectObserveFn = %GetObjectContextObjectObserve(object); | 
| 387   return objectObserveFn(object, callback, acceptList); | 395   return objectObserveFn(object, callback, acceptList); | 
| 388 } | 396 } | 
| 389 | 397 | 
| 390 | 398 | 
| 391 function NativeObjectObserve(object, callback, acceptList) { | 399 function NativeObjectObserve(object, callback, acceptList) { | 
| 392   var objectInfo = ObjectInfoGetOrCreate(object); | 400   var objectInfo = ObjectInfoGetOrCreate(object); | 
| 393   var typeList = ConvertAcceptListToTypeMap(acceptList); | 401   var typeList = ConvertAcceptListToTypeMap(acceptList); | 
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 466   var hasType = !IS_UNDEFINED(type); | 474   var hasType = !IS_UNDEFINED(type); | 
| 467   var newRecord = hasType ? | 475   var newRecord = hasType ? | 
| 468       { object: objectInfo.object, type: type } : | 476       { object: objectInfo.object, type: type } : | 
| 469       { object: objectInfo.object }; | 477       { object: objectInfo.object }; | 
| 470 | 478 | 
| 471   for (var prop in changeRecord) { | 479   for (var prop in changeRecord) { | 
| 472     if (prop === 'object' || (hasType && prop === 'type')) continue; | 480     if (prop === 'object' || (hasType && prop === 'type')) continue; | 
| 473     %DefineDataPropertyUnchecked( | 481     %DefineDataPropertyUnchecked( | 
| 474         newRecord, prop, changeRecord[prop], READ_ONLY + DONT_DELETE); | 482         newRecord, prop, changeRecord[prop], READ_ONLY + DONT_DELETE); | 
| 475   } | 483   } | 
| 476   $objectFreeze(newRecord); | 484   ObjectFreeze(newRecord); | 
| 477 | 485 | 
| 478   ObjectInfoEnqueueInternalChangeRecord(objectInfo, newRecord); | 486   ObjectInfoEnqueueInternalChangeRecord(objectInfo, newRecord); | 
| 479 } | 487 } | 
| 480 | 488 | 
| 481 | 489 | 
| 482 function ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord) { | 490 function ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord) { | 
| 483   // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 491   // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 
| 484   if (IS_SYMBOL(changeRecord.name)) return; | 492   if (IS_SYMBOL(changeRecord.name)) return; | 
| 485 | 493 | 
| 486   if (ChangeObserversIsOptimized(objectInfo.changeObservers)) { | 494   if (ChangeObserversIsOptimized(objectInfo.changeObservers)) { | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 518     return; | 526     return; | 
| 519 | 527 | 
| 520   var changeRecord = { | 528   var changeRecord = { | 
| 521     type: 'splice', | 529     type: 'splice', | 
| 522     object: array, | 530     object: array, | 
| 523     index: index, | 531     index: index, | 
| 524     removed: removed, | 532     removed: removed, | 
| 525     addedCount: addedCount | 533     addedCount: addedCount | 
| 526   }; | 534   }; | 
| 527 | 535 | 
| 528   $objectFreeze(changeRecord); | 536   ObjectFreeze(changeRecord); | 
| 529   $objectFreeze(changeRecord.removed); | 537   ObjectFreeze(changeRecord.removed); | 
| 530   ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord); | 538   ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord); | 
| 531 } | 539 } | 
| 532 | 540 | 
| 533 | 541 | 
| 534 function NotifyChange(type, object, name, oldValue) { | 542 function NotifyChange(type, object, name, oldValue) { | 
| 535   var objectInfo = ObjectInfoGet(object); | 543   var objectInfo = ObjectInfoGet(object); | 
| 536   if (!ObjectInfoHasActiveObservers(objectInfo)) | 544   if (!ObjectInfoHasActiveObservers(objectInfo)) | 
| 537     return; | 545     return; | 
| 538 | 546 | 
| 539   var changeRecord; | 547   var changeRecord; | 
| 540   if (arguments.length == 2) { | 548   if (arguments.length == 2) { | 
| 541     changeRecord = { type: type, object: object }; | 549     changeRecord = { type: type, object: object }; | 
| 542   } else if (arguments.length == 3) { | 550   } else if (arguments.length == 3) { | 
| 543     changeRecord = { type: type, object: object, name: name }; | 551     changeRecord = { type: type, object: object, name: name }; | 
| 544   } else { | 552   } else { | 
| 545     changeRecord = { | 553     changeRecord = { | 
| 546       type: type, | 554       type: type, | 
| 547       object: object, | 555       object: object, | 
| 548       name: name, | 556       name: name, | 
| 549       oldValue: oldValue | 557       oldValue: oldValue | 
| 550     }; | 558     }; | 
| 551   } | 559   } | 
| 552 | 560 | 
| 553   $objectFreeze(changeRecord); | 561   ObjectFreeze(changeRecord); | 
| 554   ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord); | 562   ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord); | 
| 555 } | 563 } | 
| 556 | 564 | 
| 557 | 565 | 
| 558 function ObjectNotifierNotify(changeRecord) { | 566 function ObjectNotifierNotify(changeRecord) { | 
| 559   if (!IS_SPEC_OBJECT(this)) | 567   if (!IS_SPEC_OBJECT(this)) | 
| 560     throw MakeTypeError(kCalledOnNonObject, "notify"); | 568     throw MakeTypeError(kCalledOnNonObject, "notify"); | 
| 561 | 569 | 
| 562   var objectInfo = ObjectInfoGetFromNotifier(this); | 570   var objectInfo = ObjectInfoGetFromNotifier(this); | 
| 563   if (IS_UNDEFINED(objectInfo)) | 571   if (IS_UNDEFINED(objectInfo)) | 
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 600     ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, changeType); | 608     ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, changeType); | 
| 601 } | 609 } | 
| 602 | 610 | 
| 603 | 611 | 
| 604 function ObjectGetNotifier(object) { | 612 function ObjectGetNotifier(object) { | 
| 605   if (!IS_SPEC_OBJECT(object)) | 613   if (!IS_SPEC_OBJECT(object)) | 
| 606     throw MakeTypeError(kObserveNonObject, "getNotifier", "getNotifier"); | 614     throw MakeTypeError(kObserveNonObject, "getNotifier", "getNotifier"); | 
| 607   if (%IsJSGlobalProxy(object)) | 615   if (%IsJSGlobalProxy(object)) | 
| 608     throw MakeTypeError(kObserveGlobalProxy, "getNotifier"); | 616     throw MakeTypeError(kObserveGlobalProxy, "getNotifier"); | 
| 609 | 617 | 
| 610   if ($objectIsFrozen(object)) return null; | 618   if (ObjectIsFrozen(object)) return null; | 
| 611 | 619 | 
| 612   if (!%ObjectWasCreatedInCurrentOrigin(object)) return null; | 620   if (!%ObjectWasCreatedInCurrentOrigin(object)) return null; | 
| 613 | 621 | 
| 614   var getNotifierFn = %GetObjectContextObjectGetNotifier(object); | 622   var getNotifierFn = %GetObjectContextObjectGetNotifier(object); | 
| 615   return getNotifierFn(object); | 623   return getNotifierFn(object); | 
| 616 } | 624 } | 
| 617 | 625 | 
| 618 | 626 | 
| 619 function NativeObjectGetNotifier(object) { | 627 function NativeObjectGetNotifier(object) { | 
| 620   var objectInfo = ObjectInfoGetOrCreate(object); | 628   var objectInfo = ObjectInfoGetOrCreate(object); | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 658   if (!IS_NULL(pendingObservers)) { | 666   if (!IS_NULL(pendingObservers)) { | 
| 659     SetPendingObservers(null); | 667     SetPendingObservers(null); | 
| 660     for (var i in pendingObservers) { | 668     for (var i in pendingObservers) { | 
| 661       CallbackDeliverPending(pendingObservers[i]); | 669       CallbackDeliverPending(pendingObservers[i]); | 
| 662     } | 670     } | 
| 663   } | 671   } | 
| 664 } | 672 } | 
| 665 | 673 | 
| 666 // ------------------------------------------------------------------- | 674 // ------------------------------------------------------------------- | 
| 667 | 675 | 
| 668 $installFunctions(GlobalObject, DONT_ENUM, [ | 676 utils.InstallFunctions(GlobalObject, DONT_ENUM, [ | 
| 669   "deliverChangeRecords", ObjectDeliverChangeRecords, | 677   "deliverChangeRecords", ObjectDeliverChangeRecords, | 
| 670   "getNotifier", ObjectGetNotifier, | 678   "getNotifier", ObjectGetNotifier, | 
| 671   "observe", ObjectObserve, | 679   "observe", ObjectObserve, | 
| 672   "unobserve", ObjectUnobserve | 680   "unobserve", ObjectUnobserve | 
| 673 ]); | 681 ]); | 
| 674 $installFunctions(GlobalArray, DONT_ENUM, [ | 682 utils.InstallFunctions(GlobalArray, DONT_ENUM, [ | 
| 675   "observe", ArrayObserve, | 683   "observe", ArrayObserve, | 
| 676   "unobserve", ArrayUnobserve | 684   "unobserve", ArrayUnobserve | 
| 677 ]); | 685 ]); | 
| 678 $installFunctions(notifierPrototype, DONT_ENUM, [ | 686 utils.InstallFunctions(notifierPrototype, DONT_ENUM, [ | 
| 679   "notify", ObjectNotifierNotify, | 687   "notify", ObjectNotifierNotify, | 
| 680   "performChange", ObjectNotifierPerformChange | 688   "performChange", ObjectNotifierPerformChange | 
| 681 ]); | 689 ]); | 
| 682 | 690 | 
| 683 $observeNotifyChange = NotifyChange; | 691 $observeNotifyChange = NotifyChange; | 
| 684 $observeEnqueueSpliceRecord = EnqueueSpliceRecord; | 692 $observeEnqueueSpliceRecord = EnqueueSpliceRecord; | 
| 685 $observeBeginPerformSplice = BeginPerformSplice; | 693 $observeBeginPerformSplice = BeginPerformSplice; | 
| 686 $observeEndPerformSplice = EndPerformSplice; | 694 $observeEndPerformSplice = EndPerformSplice; | 
| 687 $observeNativeObjectObserve = NativeObjectObserve; | 695 $observeNativeObjectObserve = NativeObjectObserve; | 
| 688 $observeNativeObjectGetNotifier = NativeObjectGetNotifier; | 696 $observeNativeObjectGetNotifier = NativeObjectGetNotifier; | 
| 689 $observeNativeObjectNotifierPerformChange = NativeObjectNotifierPerformChange; | 697 $observeNativeObjectNotifierPerformChange = NativeObjectNotifierPerformChange; | 
| 690 | 698 | 
| 691 }) | 699 }) | 
| OLD | NEW | 
|---|