Chromium Code Reviews| 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 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 393 } | 393 } |
| 394 | 394 |
| 395 function ObserverEnqueueIfActive(observer, objectInfo, changeRecord, | 395 function ObserverEnqueueIfActive(observer, objectInfo, changeRecord, |
| 396 needsAccessCheck) { | 396 needsAccessCheck) { |
| 397 if (!ObserverIsActive(observer, objectInfo) || | 397 if (!ObserverIsActive(observer, objectInfo) || |
| 398 !TypeMapHasType(ObserverGetAcceptTypes(observer), changeRecord.type)) { | 398 !TypeMapHasType(ObserverGetAcceptTypes(observer), changeRecord.type)) { |
| 399 return; | 399 return; |
| 400 } | 400 } |
| 401 | 401 |
| 402 var callback = ObserverGetCallback(observer); | 402 var callback = ObserverGetCallback(observer); |
| 403 if (needsAccessCheck && | 403 if (needsAccessCheck && !%IsAccessAllowedForObserver(callback, |
| 404 // Drop all splice records on the floor for access-checked objects | 404 changeRecord.object, |
| 405 (changeRecord.type == 'splice' || | 405 changeRecord)) { |
| 406 !%IsAccessAllowedForObserver( | |
| 407 callback, changeRecord.object, changeRecord.name))) { | |
| 408 return; | 406 return; |
| 409 } | 407 } |
| 410 | 408 |
| 411 var callbackInfo = CallbackInfoNormalize(callback); | 409 var callbackInfo = CallbackInfoNormalize(callback); |
| 412 if (IS_NULL(GetPendingObservers())) { | 410 if (IS_NULL(GetPendingObservers())) { |
| 413 SetPendingObservers(nullProtoObject()) | 411 SetPendingObservers(nullProtoObject()) |
| 414 GetMicrotaskQueue().push(ObserveMicrotaskRunner); | 412 GetMicrotaskQueue().push(ObserveMicrotaskRunner); |
| 415 %SetMicrotaskPending(true); | 413 %SetMicrotaskPending(true); |
| 416 } | 414 } |
| 417 GetPendingObservers()[callbackInfo.priority] = callback; | 415 GetPendingObservers()[callbackInfo.priority] = callback; |
| 418 callbackInfo.push(changeRecord); | 416 callbackInfo.push(changeRecord); |
| 419 } | 417 } |
| 420 | 418 |
| 421 function ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, type) { | 419 function ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, type) { |
| 422 if (!ObjectInfoHasActiveObservers(objectInfo)) | 420 if (!ObjectInfoHasActiveObservers(objectInfo)) |
| 423 return; | 421 return; |
| 424 | 422 |
| 425 var hasType = !IS_UNDEFINED(type); | 423 var hasType = !IS_UNDEFINED(type); |
| 426 var newRecord = hasType ? | 424 var newRecord = hasType ? |
| 427 { object: ObjectInfoGetObject(objectInfo), type: type } : | 425 { object: ObjectInfoGetObject(objectInfo), type: type } : |
| 428 { object: ObjectInfoGetObject(objectInfo) }; | 426 { object: ObjectInfoGetObject(objectInfo) }; |
| 429 | 427 |
| 430 for (var prop in changeRecord) { | 428 for (var prop in changeRecord) { |
| 431 if (prop === 'object' || (hasType && prop === 'type')) continue; | 429 if (prop === 'object' || (hasType && prop === 'type')) continue; |
| 432 %DefineOrRedefineDataProperty(newRecord, prop, changeRecord[prop], | 430 %DefineOrRedefineDataProperty(newRecord, prop, changeRecord[prop], |
| 433 READ_ONLY + DONT_DELETE); | 431 READ_ONLY + DONT_DELETE); |
| 434 } | 432 } |
| 435 ObjectFreeze(newRecord); | 433 ObjectFreeze(newRecord); |
| 436 | 434 |
| 437 ObjectInfoEnqueueInternalChangeRecord(objectInfo, newRecord, | 435 ObjectInfoEnqueueInternalChangeRecord(objectInfo, newRecord); |
| 438 true /* skip access check */); | |
| 439 } | 436 } |
| 440 | 437 |
| 441 function ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord, | 438 function ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord) { |
| 442 skipAccessCheck) { | |
| 443 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 439 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 444 if (IS_SYMBOL(changeRecord.name)) return; | 440 if (IS_SYMBOL(changeRecord.name)) return; |
| 445 | 441 |
| 446 var needsAccessCheck = !skipAccessCheck && | 442 var needsAccessCheck = %IsAccessCheckNeeded(changeRecord.object); |
|
rossberg
2014/04/30 11:28:32
I believe you always need to do the same-origin ch
rafaelw
2014/05/02 03:22:32
Done.
| |
| 447 %IsAccessCheckNeeded(changeRecord.object); | |
| 448 | 443 |
| 449 if (ChangeObserversIsOptimized(objectInfo.changeObservers)) { | 444 if (ChangeObserversIsOptimized(objectInfo.changeObservers)) { |
| 450 var observer = objectInfo.changeObservers; | 445 var observer = objectInfo.changeObservers; |
| 451 ObserverEnqueueIfActive(observer, objectInfo, changeRecord, | 446 ObserverEnqueueIfActive(observer, objectInfo, changeRecord, |
| 452 needsAccessCheck); | 447 needsAccessCheck); |
| 453 return; | 448 return; |
| 454 } | 449 } |
| 455 | 450 |
| 456 for (var priority in objectInfo.changeObservers) { | 451 for (var priority in objectInfo.changeObservers) { |
| 457 var observer = objectInfo.changeObservers[priority]; | 452 var observer = objectInfo.changeObservers[priority]; |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 555 if (IS_SPEC_OBJECT(changeRecord)) | 550 if (IS_SPEC_OBJECT(changeRecord)) |
| 556 ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, changeType); | 551 ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, changeType); |
| 557 } | 552 } |
| 558 | 553 |
| 559 function ObjectGetNotifier(object) { | 554 function ObjectGetNotifier(object) { |
| 560 if (!IS_SPEC_OBJECT(object)) | 555 if (!IS_SPEC_OBJECT(object)) |
| 561 throw MakeTypeError("observe_non_object", ["getNotifier"]); | 556 throw MakeTypeError("observe_non_object", ["getNotifier"]); |
| 562 | 557 |
| 563 if (ObjectIsFrozen(object)) return null; | 558 if (ObjectIsFrozen(object)) return null; |
| 564 | 559 |
| 560 if (!%ObjectWasCreatedInCurrentOrigin(object)) return null; | |
| 561 | |
| 565 var objectInfo = ObjectInfoGetOrCreate(object); | 562 var objectInfo = ObjectInfoGetOrCreate(object); |
| 566 return ObjectInfoGetNotifier(objectInfo); | 563 return ObjectInfoGetNotifier(objectInfo); |
| 567 } | 564 } |
| 568 | 565 |
| 569 function CallbackDeliverPending(callback) { | 566 function CallbackDeliverPending(callback) { |
| 570 var callbackInfo = GetCallbackInfoMap().get(callback); | 567 var callbackInfo = GetCallbackInfoMap().get(callback); |
| 571 if (IS_UNDEFINED(callbackInfo) || IS_NUMBER(callbackInfo)) | 568 if (IS_UNDEFINED(callbackInfo) || IS_NUMBER(callbackInfo)) |
| 572 return false; | 569 return false; |
| 573 | 570 |
| 574 // Clear the pending change records from callback and return it to its | 571 // Clear the pending change records from callback and return it to its |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 616 InstallFunctions($Array, DONT_ENUM, $Array( | 613 InstallFunctions($Array, DONT_ENUM, $Array( |
| 617 "observe", ArrayObserve, | 614 "observe", ArrayObserve, |
| 618 "unobserve", ArrayUnobserve | 615 "unobserve", ArrayUnobserve |
| 619 )); | 616 )); |
| 620 InstallFunctions(notifierPrototype, DONT_ENUM, $Array( | 617 InstallFunctions(notifierPrototype, DONT_ENUM, $Array( |
| 621 "notify", ObjectNotifierNotify, | 618 "notify", ObjectNotifierNotify, |
| 622 "performChange", ObjectNotifierPerformChange | 619 "performChange", ObjectNotifierPerformChange |
| 623 )); | 620 )); |
| 624 } | 621 } |
| 625 | 622 |
| 626 // Disable Object.observe API for M35. | 623 SetupObjectObserve(); |
| 627 // SetupObjectObserve(); | |
| OLD | NEW |