Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(422)

Side by Side Diff: src/array.js

Issue 16150003: Revert "Implement ObservedArrayPop, ObservedArrayShift, ObservedArrayUnshift & ObservedArraySplice" (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | test/mjsunit/harmony/object-observe.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 separator = NonStringToString(separator); 388 separator = NonStringToString(separator);
389 } 389 }
390 390
391 var result = %_FastAsciiArrayJoin(this, separator); 391 var result = %_FastAsciiArrayJoin(this, separator);
392 if (!IS_UNDEFINED(result)) return result; 392 if (!IS_UNDEFINED(result)) return result;
393 393
394 return Join(this, length, separator, ConvertToString); 394 return Join(this, length, separator, ConvertToString);
395 } 395 }
396 396
397 397
398 function ObservedArrayPop(n) {
399 n--;
400 var value = this[n];
401
402 EnqueueSpliceRecord(this, n, [value], 1, 0);
403
404 try {
405 BeginPerformSplice(this);
406 delete this[n];
407 this.length = n;
408 } finally {
409 EndPerformSplice(this);
410 }
411
412 return value;
413 }
414
415 // Removes the last element from the array and returns it. See 398 // Removes the last element from the array and returns it. See
416 // ECMA-262, section 15.4.4.6. 399 // ECMA-262, section 15.4.4.6.
417 function ArrayPop() { 400 function ArrayPop() {
418 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 401 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
419 throw MakeTypeError("called_on_null_or_undefined", 402 throw MakeTypeError("called_on_null_or_undefined",
420 ["Array.prototype.pop"]); 403 ["Array.prototype.pop"]);
421 } 404 }
422 405
423 var n = TO_UINT32(this.length); 406 var n = TO_UINT32(this.length);
424 if (n == 0) { 407 if (n == 0) {
425 this.length = n; 408 this.length = n;
426 return; 409 return;
427 } 410 }
428
429 if (%IsObserved(this))
430 return ObservedArrayPop.call(this, n);
431
432 n--; 411 n--;
433 var value = this[n]; 412 var value = this[n];
434 delete this[n]; 413 delete this[n];
435 this.length = n; 414 this.length = n;
436 return value; 415 return value;
437 } 416 }
438 417
439 418
440 function ObservedArrayPush() { 419 function ObservedArrayPush() {
441 var n = TO_UINT32(this.length); 420 var n = TO_UINT32(this.length);
442 var m = %_ArgumentsLength(); 421 var m = %_ArgumentsLength();
443 422
444 EnqueueSpliceRecord(this, n, [], 0, m); 423 EnqueueSpliceRecord(this, n, [], 0, m);
445 424
446 try { 425 try {
447 BeginPerformSplice(this); 426 BeginPerformSplice(this);
427
448 for (var i = 0; i < m; i++) { 428 for (var i = 0; i < m; i++) {
449 this[i+n] = %_Arguments(i); 429 this[i+n] = %_Arguments(i);
450 } 430 }
451 this.length = n + m; 431 this.length = n + m;
452 } finally { 432 } finally {
453 EndPerformSplice(this); 433 EndPerformSplice(this);
454 } 434 }
455 435
456 return this.length; 436 return this.length;
457 } 437 }
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 if (!IS_UNDEFINED(current_j) || j in this) { 551 if (!IS_UNDEFINED(current_j) || j in this) {
572 this[i] = current_j; 552 this[i] = current_j;
573 delete this[j]; 553 delete this[j];
574 } 554 }
575 } 555 }
576 } 556 }
577 return this; 557 return this;
578 } 558 }
579 559
580 560
581 function ObservedArrayShift(len) {
582 var first = this[0];
583
584 EnqueueSpliceRecord(this, 0, [first], 1, 0);
585
586 try {
587 BeginPerformSplice(this);
588 SimpleMove(this, 0, 1, len, 0);
589 this.length = len - 1;
590 } finally {
591 EndPerformSplice(this);
592 }
593
594 return first;
595 }
596
597 function ArrayShift() { 561 function ArrayShift() {
598 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 562 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
599 throw MakeTypeError("called_on_null_or_undefined", 563 throw MakeTypeError("called_on_null_or_undefined",
600 ["Array.prototype.shift"]); 564 ["Array.prototype.shift"]);
601 } 565 }
602 566
603 var len = TO_UINT32(this.length); 567 var len = TO_UINT32(this.length);
604 568
605 if (len === 0) { 569 if (len === 0) {
606 this.length = 0; 570 this.length = 0;
607 return; 571 return;
608 } 572 }
609 573
610 if (%IsObserved(this))
611 return ObservedArrayShift.call(this, len);
612
613 var first = this[0]; 574 var first = this[0];
614 575
615 if (IS_ARRAY(this)) { 576 if (IS_ARRAY(this) && !%IsObserved(this)) {
616 SmartMove(this, 0, 1, len, 0); 577 SmartMove(this, 0, 1, len, 0);
617 } else { 578 } else {
618 SimpleMove(this, 0, 1, len, 0); 579 SimpleMove(this, 0, 1, len, 0);
619 } 580 }
620 581
621 this.length = len - 1; 582 this.length = len - 1;
622 583
623 return first; 584 return first;
624 } 585 }
625 586
626 function ObservedArrayUnshift() {
627 var len = TO_UINT32(this.length);
628 var num_arguments = %_ArgumentsLength();
629
630 EnqueueSpliceRecord(this, 0, [], 0, num_arguments);
631
632 try {
633 BeginPerformSplice(this);
634 SimpleMove(this, 0, 0, len, num_arguments);
635 for (var i = 0; i < num_arguments; i++) {
636 this[i] = %_Arguments(i);
637 }
638 this.length = len + num_arguments;
639 } finally {
640 EndPerformSplice(this);
641 }
642
643 return len + num_arguments;
644 }
645 587
646 function ArrayUnshift(arg1) { // length == 1 588 function ArrayUnshift(arg1) { // length == 1
647 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 589 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
648 throw MakeTypeError("called_on_null_or_undefined", 590 throw MakeTypeError("called_on_null_or_undefined",
649 ["Array.prototype.unshift"]); 591 ["Array.prototype.unshift"]);
650 } 592 }
651 593
652 if (%IsObserved(this))
653 return ObservedArrayUnshift.apply(this, arguments);
654
655 var len = TO_UINT32(this.length); 594 var len = TO_UINT32(this.length);
656 var num_arguments = %_ArgumentsLength(); 595 var num_arguments = %_ArgumentsLength();
657 596
658 if (IS_ARRAY(this)) { 597 if (IS_ARRAY(this) && !%IsObserved(this)) {
659 SmartMove(this, 0, 0, len, num_arguments); 598 SmartMove(this, 0, 0, len, num_arguments);
660 } else { 599 } else {
661 SimpleMove(this, 0, 0, len, num_arguments); 600 SimpleMove(this, 0, 0, len, num_arguments);
662 } 601 }
663 602
664 for (var i = 0; i < num_arguments; i++) { 603 for (var i = 0; i < num_arguments; i++) {
665 this[i] = %_Arguments(i); 604 this[i] = %_Arguments(i);
666 } 605 }
667 606
668 this.length = len + num_arguments; 607 this.length = len + num_arguments;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 } else { 648 } else {
710 SimpleSlice(this, start_i, end_i - start_i, len, result); 649 SimpleSlice(this, start_i, end_i - start_i, len, result);
711 } 650 }
712 651
713 result.length = end_i - start_i; 652 result.length = end_i - start_i;
714 653
715 return result; 654 return result;
716 } 655 }
717 656
718 657
719 function ComputeSpliceStartIndex(start_i, len) {
720 if (start_i < 0) {
721 start_i += len;
722 return start_i < 0 ? 0 : start_i;
723 }
724
725 return start_i > len ? len : start_i;
726 }
727
728
729 function ComputeSpliceDeleteCount(delete_count, num_arguments, len, start_i) {
730 // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is
731 // given as a request to delete all the elements from the start.
732 // And it differs from the case of undefined delete count.
733 // This does not follow ECMA-262, but we do the same for
734 // compatibility.
735 var del_count = 0;
736 if (num_arguments == 1)
737 return len - start_i;
738
739 del_count = TO_INTEGER(delete_count);
740 if (del_count < 0)
741 return 0;
742
743 if (del_count > len - start_i)
744 return len - start_i;
745
746 return del_count;
747 }
748
749
750 function ObservedArraySplice(start, delete_count) {
751 var num_arguments = %_ArgumentsLength();
752 var len = TO_UINT32(this.length);
753 var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len);
754 var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len,
755 start_i);
756 var deleted_elements = [];
757 deleted_elements.length = del_count;
758 var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0;
759
760 try {
761 BeginPerformSplice(this);
762
763 SimpleSlice(this, start_i, del_count, len, deleted_elements);
764 SimpleMove(this, start_i, del_count, len, num_elements_to_add);
765
766 // Insert the arguments into the resulting array in
767 // place of the deleted elements.
768 var i = start_i;
769 var arguments_index = 2;
770 var arguments_length = %_ArgumentsLength();
771 while (arguments_index < arguments_length) {
772 this[i++] = %_Arguments(arguments_index++);
773 }
774 this.length = len - del_count + num_elements_to_add;
775
776 } finally {
777 EndPerformSplice(this);
778 if (deleted_elements.length || num_elements_to_add) {
779 EnqueueSpliceRecord(this,
780 start_i,
781 deleted_elements.slice(),
782 deleted_elements.length,
783 num_elements_to_add);
784 }
785 }
786
787 // Return the deleted elements.
788 return deleted_elements;
789 }
790
791
792 function ArraySplice(start, delete_count) { 658 function ArraySplice(start, delete_count) {
793 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 659 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
794 throw MakeTypeError("called_on_null_or_undefined", 660 throw MakeTypeError("called_on_null_or_undefined",
795 ["Array.prototype.splice"]); 661 ["Array.prototype.splice"]);
796 } 662 }
797 663
798 if (%IsObserved(this)) 664 var num_arguments = %_ArgumentsLength();
799 return ObservedArraySplice.apply(this, arguments);
800 665
801 var num_arguments = %_ArgumentsLength();
802 var len = TO_UINT32(this.length); 666 var len = TO_UINT32(this.length);
803 var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len); 667 var start_i = TO_INTEGER(start);
804 var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len, 668
805 start_i); 669 if (start_i < 0) {
670 start_i += len;
671 if (start_i < 0) start_i = 0;
672 } else {
673 if (start_i > len) start_i = len;
674 }
675
676 // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is
677 // given as a request to delete all the elements from the start.
678 // And it differs from the case of undefined delete count.
679 // This does not follow ECMA-262, but we do the same for
680 // compatibility.
681 var del_count = 0;
682 if (num_arguments == 1) {
683 del_count = len - start_i;
684 } else {
685 del_count = TO_INTEGER(delete_count);
686 if (del_count < 0) del_count = 0;
687 if (del_count > len - start_i) del_count = len - start_i;
688 }
689
806 var deleted_elements = []; 690 var deleted_elements = [];
807 deleted_elements.length = del_count; 691 deleted_elements.length = del_count;
808 var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0; 692
693 // Number of elements to add.
694 var num_additional_args = 0;
695 if (num_arguments > 2) {
696 num_additional_args = num_arguments - 2;
697 }
809 698
810 var use_simple_splice = true; 699 var use_simple_splice = true;
700
811 if (IS_ARRAY(this) && 701 if (IS_ARRAY(this) &&
812 num_elements_to_add !== del_count) { 702 !%IsObserved(this) &&
703 num_additional_args !== del_count) {
813 // If we are only deleting/moving a few things near the end of the 704 // If we are only deleting/moving a few things near the end of the
814 // array then the simple version is going to be faster, because it 705 // array then the simple version is going to be faster, because it
815 // doesn't touch most of the array. 706 // doesn't touch most of the array.
816 var estimated_non_hole_elements = %EstimateNumberOfElements(this); 707 var estimated_non_hole_elements = %EstimateNumberOfElements(this);
817 if (len > 20 && (estimated_non_hole_elements >> 2) < (len - start_i)) { 708 if (len > 20 && (estimated_non_hole_elements >> 2) < (len - start_i)) {
818 use_simple_splice = false; 709 use_simple_splice = false;
819 } 710 }
820 } 711 }
821 712
822 if (use_simple_splice) { 713 if (use_simple_splice) {
823 SimpleSlice(this, start_i, del_count, len, deleted_elements); 714 SimpleSlice(this, start_i, del_count, len, deleted_elements);
824 SimpleMove(this, start_i, del_count, len, num_elements_to_add); 715 SimpleMove(this, start_i, del_count, len, num_additional_args);
825 } else { 716 } else {
826 SmartSlice(this, start_i, del_count, len, deleted_elements); 717 SmartSlice(this, start_i, del_count, len, deleted_elements);
827 SmartMove(this, start_i, del_count, len, num_elements_to_add); 718 SmartMove(this, start_i, del_count, len, num_additional_args);
828 } 719 }
829 720
830 // Insert the arguments into the resulting array in 721 // Insert the arguments into the resulting array in
831 // place of the deleted elements. 722 // place of the deleted elements.
832 var i = start_i; 723 var i = start_i;
833 var arguments_index = 2; 724 var arguments_index = 2;
834 var arguments_length = %_ArgumentsLength(); 725 var arguments_length = %_ArgumentsLength();
835 while (arguments_index < arguments_length) { 726 while (arguments_index < arguments_length) {
836 this[i++] = %_Arguments(arguments_index++); 727 this[i++] = %_Arguments(arguments_index++);
837 } 728 }
838 this.length = len - del_count + num_elements_to_add; 729 this.length = len - del_count + num_additional_args;
839 730
840 // Return the deleted elements. 731 // Return the deleted elements.
841 return deleted_elements; 732 return deleted_elements;
842 } 733 }
843 734
844 735
845 function ArraySort(comparefn) { 736 function ArraySort(comparefn) {
846 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 737 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
847 throw MakeTypeError("called_on_null_or_undefined", 738 throw MakeTypeError("called_on_null_or_undefined",
848 ["Array.prototype.sort"]); 739 ["Array.prototype.sort"]);
(...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after
1657 )); 1548 ));
1658 1549
1659 SetUpLockedPrototype(InternalPackedArray, $Array(), $Array( 1550 SetUpLockedPrototype(InternalPackedArray, $Array(), $Array(
1660 "join", getFunction("join", ArrayJoin), 1551 "join", getFunction("join", ArrayJoin),
1661 "pop", getFunction("pop", ArrayPop), 1552 "pop", getFunction("pop", ArrayPop),
1662 "push", getFunction("push", ArrayPush) 1553 "push", getFunction("push", ArrayPush)
1663 )); 1554 ));
1664 } 1555 }
1665 1556
1666 SetUpArray(); 1557 SetUpArray();
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/harmony/object-observe.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698