OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 751 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
762 if (!IS_UNDEFINED(index) && from <= index && | 762 if (!IS_UNDEFINED(index) && from <= index && |
763 proto.hasOwnProperty(index)) { | 763 proto.hasOwnProperty(index)) { |
764 obj[index] = void 0; | 764 obj[index] = void 0; |
765 } | 765 } |
766 } | 766 } |
767 } | 767 } |
768 } | 768 } |
769 } | 769 } |
770 } | 770 } |
771 | 771 |
| 772 function SafeRemoveArrayHoles(obj) { |
| 773 // Copy defined elements from the end to fill in all holes and undefineds |
| 774 // in the beginning of the array. Write undefineds and holes at the end |
| 775 // after loop is finished. |
| 776 var first_undefined = 0; |
| 777 var last_defined = length - 1; |
| 778 var num_holes = 0; |
| 779 while (first_undefined < last_defined) { |
| 780 // Find first undefined element. |
| 781 while (first_undefined < last_defined && |
| 782 !IS_UNDEFINED(obj[first_undefined])) { |
| 783 first_undefined++; |
| 784 } |
| 785 // Maintain the invariant num_holes = the number of holes in the original |
| 786 // array with indices <= first_undefined or > last_defined. |
| 787 if (!obj.hasOwnProperty(first_undefined)) { |
| 788 num_holes++; |
| 789 } |
| 790 |
| 791 // Find last defined element. |
| 792 while (first_undefined < last_defined && |
| 793 IS_UNDEFINED(obj[last_defined])) { |
| 794 if (!obj.hasOwnProperty(last_defined)) { |
| 795 num_holes++; |
| 796 } |
| 797 last_defined--; |
| 798 } |
| 799 if (first_undefined < last_defined) { |
| 800 // Fill in hole or undefined. |
| 801 obj[first_undefined] = obj[last_defined]; |
| 802 obj[last_defined] = void 0; |
| 803 } |
| 804 } |
| 805 // If there were any undefineds in the entire array, first_undefined |
| 806 // points to one past the last defined element. Make this true if |
| 807 // there were no undefineds, as well, so that first_undefined == number |
| 808 // of defined elements. |
| 809 if (!IS_UNDEFINED(obj[first_undefined])) first_undefined++; |
| 810 // Fill in the undefineds and the holes. There may be a hole where |
| 811 // an undefined should be and vice versa. |
| 812 var i; |
| 813 for (i = first_undefined; i < length - num_holes; i++) { |
| 814 obj[i] = void 0; |
| 815 } |
| 816 for (i = length - num_holes; i < length; i++) { |
| 817 // For compatability with Webkit, do not expose elements in the prototype. |
| 818 if (i in obj.__proto__) { |
| 819 obj[i] = void 0; |
| 820 } else { |
| 821 delete obj[i]; |
| 822 } |
| 823 } |
| 824 |
| 825 // Return the number of defined elements. |
| 826 return first_undefined; |
| 827 } |
| 828 |
772 var length = ToUint32(this.length); | 829 var length = ToUint32(this.length); |
773 if (length < 2) return this; | 830 if (length < 2) return this; |
774 | 831 |
775 var is_array = IS_ARRAY(this); | 832 var is_array = IS_ARRAY(this); |
776 var max_prototype_element; | 833 var max_prototype_element; |
777 if (!is_array) { | 834 if (!is_array) { |
778 // For compatibility with JSC, we also sort elements inherited from | 835 // For compatibility with JSC, we also sort elements inherited from |
779 // the prototype chain on non-Array objects. | 836 // the prototype chain on non-Array objects. |
780 // We do this by copying them to this object and sorting only | 837 // We do this by copying them to this object and sorting only |
781 // local elements. This is not very efficient, but sorting with | 838 // local elements. This is not very efficient, but sorting with |
782 // inherited elements happens very, very rarely, if at all. | 839 // inherited elements happens very, very rarely, if at all. |
783 // The specification allows "implementation dependent" behavior | 840 // The specification allows "implementation dependent" behavior |
784 // if an element on the prototype chain has an element that | 841 // if an element on the prototype chain has an element that |
785 // might interact with sorting. | 842 // might interact with sorting. |
786 max_prototype_element = CopyFromPrototype(this, length); | 843 max_prototype_element = CopyFromPrototype(this, length); |
787 } | 844 } |
788 | 845 |
789 var num_non_undefined = %RemoveArrayHoles(this, length); | 846 var num_non_undefined = %RemoveArrayHoles(this, length); |
| 847 if (num_non_undefined == -1) { |
| 848 // There were indexed accessors in the array. Move array holes and |
| 849 // undefineds to the end using a Javascript function that is safe |
| 850 // in the presence of accessors. |
| 851 num_non_undefined = SafeRemoveArrayHoles(this); |
| 852 } |
790 | 853 |
791 QuickSort(this, 0, num_non_undefined); | 854 QuickSort(this, 0, num_non_undefined); |
792 | 855 |
793 if (!is_array && (num_non_undefined + 1 < max_prototype_element)) { | 856 if (!is_array && (num_non_undefined + 1 < max_prototype_element)) { |
794 // For compatibility with JSC, we shadow any elements in the prototype | 857 // For compatibility with JSC, we shadow any elements in the prototype |
795 // chain that has become exposed by sort moving a hole to its position. | 858 // chain that has become exposed by sort moving a hole to its position. |
796 ShadowPrototypeElements(this, num_non_undefined, max_prototype_element); | 859 ShadowPrototypeElements(this, num_non_undefined, max_prototype_element); |
797 } | 860 } |
798 | 861 |
799 return this; | 862 return this; |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1046 ArrayIndexOf: 1, | 1109 ArrayIndexOf: 1, |
1047 ArrayLastIndexOf: 1, | 1110 ArrayLastIndexOf: 1, |
1048 ArrayPush: 1, | 1111 ArrayPush: 1, |
1049 ArrayReduce: 1, | 1112 ArrayReduce: 1, |
1050 ArrayReduceRight: 1 | 1113 ArrayReduceRight: 1 |
1051 }); | 1114 }); |
1052 } | 1115 } |
1053 | 1116 |
1054 | 1117 |
1055 SetupArray(); | 1118 SetupArray(); |
OLD | NEW |