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 |