| 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 "use strict"; | 5 "use strict"; |
| 6 | 6 |
| 7 // Overview: | 7 // Overview: |
| 8 // | 8 // |
| 9 // This file contains all of the routing and accounting for Object.observe. | 9 // This file contains all of the routing and accounting for Object.observe. |
| 10 // User code will interact with these mechanisms via the Object.observe APIs | 10 // User code will interact with these mechanisms via the Object.observe APIs |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 // (i.e. not Object.deliverChangeRecords), this is the mechanism by which | 28 // (i.e. not Object.deliverChangeRecords), this is the mechanism by which |
| 29 // callbacks are invoked in the proper order until there are no more | 29 // callbacks are invoked in the proper order until there are no more |
| 30 // change records pending to a callback. | 30 // change records pending to a callback. |
| 31 // | 31 // |
| 32 // Note that in order to reduce allocation and processing costs, the | 32 // Note that in order to reduce allocation and processing costs, the |
| 33 // implementation of (1) and (2) have "optimized" states which represent | 33 // implementation of (1) and (2) have "optimized" states which represent |
| 34 // common cases which can be handled more efficiently. | 34 // common cases which can be handled more efficiently. |
| 35 | 35 |
| 36 var observationState; | 36 var observationState; |
| 37 | 37 |
| 38 function GetObservationState() { | 38 function GetObservationStateJS() { |
| 39 if (IS_UNDEFINED(observationState)) | 39 if (IS_UNDEFINED(observationState)) |
| 40 observationState = %GetObservationState(); | 40 observationState = %GetObservationState(); |
| 41 | 41 |
| 42 if (IS_UNDEFINED(observationState.callbackInfoMap)) { | 42 if (IS_UNDEFINED(observationState.callbackInfoMap)) { |
| 43 observationState.callbackInfoMap = %ObservationWeakMapCreate(); | 43 observationState.callbackInfoMap = %ObservationWeakMapCreate(); |
| 44 observationState.objectInfoMap = %ObservationWeakMapCreate(); | 44 observationState.objectInfoMap = %ObservationWeakMapCreate(); |
| 45 observationState.notifierObjectInfoMap = %ObservationWeakMapCreate(); | 45 observationState.notifierObjectInfoMap = %ObservationWeakMapCreate(); |
| 46 observationState.pendingObservers = null; | 46 observationState.pendingObservers = null; |
| 47 observationState.nextCallbackPriority = 0; | 47 observationState.nextCallbackPriority = 0; |
| 48 } | 48 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 69 }; | 69 }; |
| 70 | 70 |
| 71 return MapWrapper; | 71 return MapWrapper; |
| 72 } | 72 } |
| 73 | 73 |
| 74 var contextMaps; | 74 var contextMaps; |
| 75 | 75 |
| 76 function GetContextMaps() { | 76 function GetContextMaps() { |
| 77 if (IS_UNDEFINED(contextMaps)) { | 77 if (IS_UNDEFINED(contextMaps)) { |
| 78 var map = GetWeakMapWrapper(); | 78 var map = GetWeakMapWrapper(); |
| 79 var observationState = GetObservationState(); | 79 var observationState = GetObservationStateJS(); |
| 80 contextMaps = { | 80 contextMaps = { |
| 81 callbackInfoMap: new map(observationState.callbackInfoMap), | 81 callbackInfoMap: new map(observationState.callbackInfoMap), |
| 82 objectInfoMap: new map(observationState.objectInfoMap), | 82 objectInfoMap: new map(observationState.objectInfoMap), |
| 83 notifierObjectInfoMap: new map(observationState.notifierObjectInfoMap) | 83 notifierObjectInfoMap: new map(observationState.notifierObjectInfoMap) |
| 84 }; | 84 }; |
| 85 } | 85 } |
| 86 | 86 |
| 87 return contextMaps; | 87 return contextMaps; |
| 88 } | 88 } |
| 89 | 89 |
| 90 function GetCallbackInfoMap() { | 90 function GetCallbackInfoMap() { |
| 91 return GetContextMaps().callbackInfoMap; | 91 return GetContextMaps().callbackInfoMap; |
| 92 } | 92 } |
| 93 | 93 |
| 94 function GetObjectInfoMap() { | 94 function GetObjectInfoMap() { |
| 95 return GetContextMaps().objectInfoMap; | 95 return GetContextMaps().objectInfoMap; |
| 96 } | 96 } |
| 97 | 97 |
| 98 function GetNotifierObjectInfoMap() { | 98 function GetNotifierObjectInfoMap() { |
| 99 return GetContextMaps().notifierObjectInfoMap; | 99 return GetContextMaps().notifierObjectInfoMap; |
| 100 } | 100 } |
| 101 | 101 |
| 102 function GetPendingObservers() { | 102 function GetPendingObservers() { |
| 103 return GetObservationState().pendingObservers; | 103 return GetObservationStateJS().pendingObservers; |
| 104 } | 104 } |
| 105 | 105 |
| 106 function SetPendingObservers(pendingObservers) { | 106 function SetPendingObservers(pendingObservers) { |
| 107 GetObservationState().pendingObservers = pendingObservers; | 107 GetObservationStateJS().pendingObservers = pendingObservers; |
| 108 } | 108 } |
| 109 | 109 |
| 110 function GetNextCallbackPriority() { | 110 function GetNextCallbackPriority() { |
| 111 return GetObservationState().nextCallbackPriority++; | 111 return GetObservationStateJS().nextCallbackPriority++; |
| 112 } | 112 } |
| 113 | 113 |
| 114 function nullProtoObject() { | 114 function nullProtoObject() { |
| 115 return { __proto__: null }; | 115 return { __proto__: null }; |
| 116 } | 116 } |
| 117 | 117 |
| 118 function TypeMapCreate() { | 118 function TypeMapCreate() { |
| 119 return nullProtoObject(); | 119 return nullProtoObject(); |
| 120 } | 120 } |
| 121 | 121 |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 var hasType = !IS_UNDEFINED(type); | 433 var hasType = !IS_UNDEFINED(type); |
| 434 var newRecord = hasType ? | 434 var newRecord = hasType ? |
| 435 { object: ObjectInfoGetObject(objectInfo), type: type } : | 435 { object: ObjectInfoGetObject(objectInfo), type: type } : |
| 436 { object: ObjectInfoGetObject(objectInfo) }; | 436 { object: ObjectInfoGetObject(objectInfo) }; |
| 437 | 437 |
| 438 for (var prop in changeRecord) { | 438 for (var prop in changeRecord) { |
| 439 if (prop === 'object' || (hasType && prop === 'type')) continue; | 439 if (prop === 'object' || (hasType && prop === 'type')) continue; |
| 440 %DefineOrRedefineDataProperty(newRecord, prop, changeRecord[prop], | 440 %DefineOrRedefineDataProperty(newRecord, prop, changeRecord[prop], |
| 441 READ_ONLY + DONT_DELETE); | 441 READ_ONLY + DONT_DELETE); |
| 442 } | 442 } |
| 443 ObjectFreeze(newRecord); | 443 ObjectFreezeJS(newRecord); |
| 444 | 444 |
| 445 ObjectInfoEnqueueInternalChangeRecord(objectInfo, newRecord); | 445 ObjectInfoEnqueueInternalChangeRecord(objectInfo, newRecord); |
| 446 } | 446 } |
| 447 | 447 |
| 448 function ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord) { | 448 function ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord) { |
| 449 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 449 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 450 if (IS_SYMBOL(changeRecord.name)) return; | 450 if (IS_SYMBOL(changeRecord.name)) return; |
| 451 | 451 |
| 452 if (ChangeObserversIsOptimized(objectInfo.changeObservers)) { | 452 if (ChangeObserversIsOptimized(objectInfo.changeObservers)) { |
| 453 var observer = objectInfo.changeObservers; | 453 var observer = objectInfo.changeObservers; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 481 return; | 481 return; |
| 482 | 482 |
| 483 var changeRecord = { | 483 var changeRecord = { |
| 484 type: 'splice', | 484 type: 'splice', |
| 485 object: array, | 485 object: array, |
| 486 index: index, | 486 index: index, |
| 487 removed: removed, | 487 removed: removed, |
| 488 addedCount: addedCount | 488 addedCount: addedCount |
| 489 }; | 489 }; |
| 490 | 490 |
| 491 ObjectFreeze(changeRecord); | 491 ObjectFreezeJS(changeRecord); |
| 492 ObjectFreeze(changeRecord.removed); | 492 ObjectFreezeJS(changeRecord.removed); |
| 493 ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord); | 493 ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord); |
| 494 } | 494 } |
| 495 | 495 |
| 496 function NotifyChange(type, object, name, oldValue) { | 496 function NotifyChange(type, object, name, oldValue) { |
| 497 var objectInfo = ObjectInfoGet(object); | 497 var objectInfo = ObjectInfoGet(object); |
| 498 if (!ObjectInfoHasActiveObservers(objectInfo)) | 498 if (!ObjectInfoHasActiveObservers(objectInfo)) |
| 499 return; | 499 return; |
| 500 | 500 |
| 501 var changeRecord; | 501 var changeRecord; |
| 502 if (arguments.length == 2) { | 502 if (arguments.length == 2) { |
| 503 changeRecord = { type: type, object: object }; | 503 changeRecord = { type: type, object: object }; |
| 504 } else if (arguments.length == 3) { | 504 } else if (arguments.length == 3) { |
| 505 changeRecord = { type: type, object: object, name: name }; | 505 changeRecord = { type: type, object: object, name: name }; |
| 506 } else { | 506 } else { |
| 507 changeRecord = { | 507 changeRecord = { |
| 508 type: type, | 508 type: type, |
| 509 object: object, | 509 object: object, |
| 510 name: name, | 510 name: name, |
| 511 oldValue: oldValue | 511 oldValue: oldValue |
| 512 }; | 512 }; |
| 513 } | 513 } |
| 514 | 514 |
| 515 ObjectFreeze(changeRecord); | 515 ObjectFreezeJS(changeRecord); |
| 516 ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord); | 516 ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord); |
| 517 } | 517 } |
| 518 | 518 |
| 519 var notifierPrototype = {}; | 519 var notifierPrototype = {}; |
| 520 | 520 |
| 521 function ObjectNotifierNotify(changeRecord) { | 521 function ObjectNotifierNotify(changeRecord) { |
| 522 if (!IS_SPEC_OBJECT(this)) | 522 if (!IS_SPEC_OBJECT(this)) |
| 523 throw MakeTypeError("called_on_non_object", ["notify"]); | 523 throw MakeTypeError("called_on_non_object", ["notify"]); |
| 524 | 524 |
| 525 var objectInfo = ObjectInfoGetFromNotifier(this); | 525 var objectInfo = ObjectInfoGetFromNotifier(this); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 630 "observe", ArrayObserve, | 630 "observe", ArrayObserve, |
| 631 "unobserve", ArrayUnobserve | 631 "unobserve", ArrayUnobserve |
| 632 )); | 632 )); |
| 633 InstallFunctions(notifierPrototype, DONT_ENUM, $Array( | 633 InstallFunctions(notifierPrototype, DONT_ENUM, $Array( |
| 634 "notify", ObjectNotifierNotify, | 634 "notify", ObjectNotifierNotify, |
| 635 "performChange", ObjectNotifierPerformChange | 635 "performChange", ObjectNotifierPerformChange |
| 636 )); | 636 )); |
| 637 } | 637 } |
| 638 | 638 |
| 639 SetupObjectObserve(); | 639 SetupObjectObserve(); |
| OLD | NEW |