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 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
637 | 637 |
638 // Return the deleted elements. | 638 // Return the deleted elements. |
639 return deleted_elements; | 639 return deleted_elements; |
640 } | 640 } |
641 | 641 |
642 | 642 |
643 function ArraySort(comparefn) { | 643 function ArraySort(comparefn) { |
644 // In-place QuickSort algorithm. | 644 // In-place QuickSort algorithm. |
645 // For short (length <= 22) arrays, insertion sort is used for efficiency. | 645 // For short (length <= 22) arrays, insertion sort is used for efficiency. |
646 | 646 |
| 647 var global_receiver; |
| 648 |
647 function InsertionSortWithFunc(a, from, to) { | 649 function InsertionSortWithFunc(a, from, to) { |
648 for (var i = from + 1; i < to; i++) { | 650 for (var i = from + 1; i < to; i++) { |
649 var element = a[i]; | 651 var element = a[i]; |
650 // place element in a[from..i[ | 652 // place element in a[from..i[ |
651 // binary search | 653 // binary search |
652 var min = from; | 654 var min = from; |
653 var max = i; | 655 var max = i; |
654 // The search interval is a[min..max[ | 656 // The search interval is a[min..max[ |
655 while (min < max) { | 657 while (min < max) { |
656 var mid = min + ((max - min) >> 1); | 658 var mid = min + ((max - min) >> 1); |
657 var order = (a[mid] === element) ? | 659 var order = %_CallFunction(global_receiver, a[mid], element, comparefn); |
658 0 : comparefn.call(null, a[mid], element); | |
659 if (order == 0) { | 660 if (order == 0) { |
660 min = max = mid; | 661 min = max = mid; |
661 break; | 662 break; |
662 } | 663 } |
663 if (order < 0) { | 664 if (order < 0) { |
664 min = mid + 1; | 665 min = mid + 1; |
665 } else { | 666 } else { |
666 max = mid; | 667 max = mid; |
667 } | 668 } |
668 } | 669 } |
(...skipping 16 matching lines...) Expand all Loading... |
685 // Issue 95: Keep the pivot element out of the comparisons to avoid | 686 // Issue 95: Keep the pivot element out of the comparisons to avoid |
686 // infinite recursion if comparefn(pivot, pivot) != 0. | 687 // infinite recursion if comparefn(pivot, pivot) != 0. |
687 a[pivot_index] = a[from]; | 688 a[pivot_index] = a[from]; |
688 a[from] = pivot; | 689 a[from] = pivot; |
689 var low_end = from; // Upper bound of the elements lower than pivot. | 690 var low_end = from; // Upper bound of the elements lower than pivot. |
690 var high_start = to; // Lower bound of the elements greater than pivot. | 691 var high_start = to; // Lower bound of the elements greater than pivot. |
691 // From low_end to i are elements equal to pivot. | 692 // From low_end to i are elements equal to pivot. |
692 // From i to high_start are elements that haven't been compared yet. | 693 // From i to high_start are elements that haven't been compared yet. |
693 for (var i = from + 1; i < high_start; ) { | 694 for (var i = from + 1; i < high_start; ) { |
694 var element = a[i]; | 695 var element = a[i]; |
695 var order = (element === pivot) ? | 696 var order = %_CallFunction(global_receiver, element, pivot, comparefn); |
696 0 : comparefn.call(null, element, pivot); | |
697 if (order < 0) { | 697 if (order < 0) { |
698 a[i] = a[low_end]; | 698 a[i] = a[low_end]; |
699 a[low_end] = element; | 699 a[low_end] = element; |
700 i++; | 700 i++; |
701 low_end++; | 701 low_end++; |
702 } else if (order > 0) { | 702 } else if (order > 0) { |
703 high_start--; | 703 high_start--; |
704 a[i] = a[high_start]; | 704 a[i] = a[high_start]; |
705 a[high_start] = element; | 705 a[high_start] = element; |
706 } else { // order == 0 | 706 } else { // order == 0 |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
931 | 931 |
932 var num_non_undefined = %RemoveArrayHoles(this, length); | 932 var num_non_undefined = %RemoveArrayHoles(this, length); |
933 if (num_non_undefined == -1) { | 933 if (num_non_undefined == -1) { |
934 // There were indexed accessors in the array. Move array holes and | 934 // There were indexed accessors in the array. Move array holes and |
935 // undefineds to the end using a Javascript function that is safe | 935 // undefineds to the end using a Javascript function that is safe |
936 // in the presence of accessors. | 936 // in the presence of accessors. |
937 num_non_undefined = SafeRemoveArrayHoles(this); | 937 num_non_undefined = SafeRemoveArrayHoles(this); |
938 } | 938 } |
939 | 939 |
940 if(IS_FUNCTION(comparefn)) { | 940 if(IS_FUNCTION(comparefn)) { |
| 941 global_receiver = %GetGlobalReceiver(); |
941 QuickSortWithFunc(this, 0, num_non_undefined); | 942 QuickSortWithFunc(this, 0, num_non_undefined); |
942 } else { | 943 } else { |
943 QuickSort(this, 0, num_non_undefined); | 944 QuickSort(this, 0, num_non_undefined); |
944 } | 945 } |
945 | 946 |
946 if (!is_array && (num_non_undefined + 1 < max_prototype_element)) { | 947 if (!is_array && (num_non_undefined + 1 < max_prototype_element)) { |
947 // For compatibility with JSC, we shadow any elements in the prototype | 948 // For compatibility with JSC, we shadow any elements in the prototype |
948 // chain that has become exposed by sort moving a hole to its position. | 949 // chain that has become exposed by sort moving a hole to its position. |
949 ShadowPrototypeElements(this, num_non_undefined, max_prototype_element); | 950 ShadowPrototypeElements(this, num_non_undefined, max_prototype_element); |
950 } | 951 } |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1210 "lastIndexOf", getFunction("lastIndexOf", ArrayLastIndexOf, 1), | 1211 "lastIndexOf", getFunction("lastIndexOf", ArrayLastIndexOf, 1), |
1211 "reduce", getFunction("reduce", ArrayReduce, 1), | 1212 "reduce", getFunction("reduce", ArrayReduce, 1), |
1212 "reduceRight", getFunction("reduceRight", ArrayReduceRight, 1) | 1213 "reduceRight", getFunction("reduceRight", ArrayReduceRight, 1) |
1213 )); | 1214 )); |
1214 | 1215 |
1215 %FinishArrayPrototypeSetup($Array.prototype); | 1216 %FinishArrayPrototypeSetup($Array.prototype); |
1216 } | 1217 } |
1217 | 1218 |
1218 | 1219 |
1219 SetupArray(); | 1220 SetupArray(); |
OLD | NEW |