Index: src/array.js |
diff --git a/src/array.js b/src/array.js |
index a718fdcc44e8fda523f15453b0b228648b9c69f1..00010de91ac0ec245cee129d5c88497c162f9b6e 100644 |
--- a/src/array.js |
+++ b/src/array.js |
@@ -644,77 +644,26 @@ function ArraySort(comparefn) { |
// In-place QuickSort algorithm. |
// For short (length <= 22) arrays, insertion sort is used for efficiency. |
- var global_receiver; |
- |
- function InsertionSortWithFunc(a, from, to) { |
- for (var i = from + 1; i < to; i++) { |
- var element = a[i]; |
- for (var j = i - 1; j >= from; j--) { |
- var tmp = a[j]; |
- var order = %_CallFunction(global_receiver, tmp, element, comparefn); |
- if (order > 0) { |
- a[j + 1] = tmp; |
- } else { |
- break; |
- } |
+ if (!IS_FUNCTION(comparefn)) { |
+ comparefn = function (x, y) { |
+ if (x === y) return 0; |
+ if (%_IsSmi(x) && %_IsSmi(y)) { |
+ return %SmiLexicographicCompare(x, y); |
} |
- a[j + 1] = element; |
- } |
+ x = ToString(x); |
+ y = ToString(y); |
+ if (x == y) return 0; |
+ else return x < y ? -1 : 1; |
+ }; |
} |
- |
- function QuickSortWithFunc(a, from, to) { |
- // Insertion sort is faster for short arrays. |
- if (to - from <= 22) { |
- InsertionSortWithFunc(a, from, to); |
- return; |
- } |
- var pivot_index = $floor($random() * (to - from)) + from; |
- var pivot = a[pivot_index]; |
- // Issue 95: Keep the pivot element out of the comparisons to avoid |
- // infinite recursion if comparefn(pivot, pivot) != 0. |
- a[pivot_index] = a[from]; |
- a[from] = pivot; |
- var low_end = from; // Upper bound of the elements lower than pivot. |
- var high_start = to; // Lower bound of the elements greater than pivot. |
- // From low_end to i are elements equal to pivot. |
- // From i to high_start are elements that haven't been compared yet. |
- for (var i = from + 1; i < high_start; ) { |
- var element = a[i]; |
- var order = %_CallFunction(global_receiver, element, pivot, comparefn); |
- if (order < 0) { |
- a[i] = a[low_end]; |
- a[low_end] = element; |
- i++; |
- low_end++; |
- } else if (order > 0) { |
- high_start--; |
- a[i] = a[high_start]; |
- a[high_start] = element; |
- } else { // order == 0 |
- i++; |
- } |
- } |
- QuickSortWithFunc(a, from, low_end); |
- QuickSortWithFunc(a, high_start, to); |
- } |
- |
- function Compare(x,y) { |
- if (x === y) return 0; |
- if (%_IsSmi(x) && %_IsSmi(y)) { |
- return %SmiLexicographicCompare(x, y); |
- } |
- x = ToString(x); |
- y = ToString(y); |
- if (x == y) return 0; |
- else return x < y ? -1 : 1; |
- }; |
+ var global_receiver = %GetGlobalReceiver(); |
function InsertionSort(a, from, to) { |
for (var i = from + 1; i < to; i++) { |
var element = a[i]; |
for (var j = i - 1; j >= from; j--) { |
var tmp = a[j]; |
- var order = Compare(tmp, element); |
+ var order = %_CallFunction(global_receiver, tmp, element, comparefn); |
if (order > 0) { |
a[j + 1] = tmp; |
} else { |
@@ -743,7 +692,7 @@ function ArraySort(comparefn) { |
// From i to high_start are elements that haven't been compared yet. |
for (var i = from + 1; i < high_start; ) { |
var element = a[i]; |
- var order = Compare(element, pivot); |
+ var order = %_CallFunction(global_receiver, element, pivot, comparefn); |
if (order < 0) { |
a[i] = a[low_end]; |
a[low_end] = element; |
@@ -903,12 +852,7 @@ function ArraySort(comparefn) { |
num_non_undefined = SafeRemoveArrayHoles(this); |
} |
- if(IS_FUNCTION(comparefn)) { |
- global_receiver = %GetGlobalReceiver(); |
- QuickSortWithFunc(this, 0, num_non_undefined); |
- } else { |
- QuickSort(this, 0, num_non_undefined); |
- } |
+ QuickSort(this, 0, num_non_undefined); |
if (!is_array && (num_non_undefined + 1 < max_prototype_element)) { |
// For compatibility with JSC, we shadow any elements in the prototype |