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