| 1135 | } |
| 1136 | |
| 1137 | private static Scriptable sort(Context cx, Scriptable o, Comparator<Object> comparator) { |
| 1138 | long llength = getLengthProperty(cx, o); |
| 1139 | final int length = (int) llength; |
| 1140 | if (llength != length) { |
| 1141 | throw Context.reportRuntimeErrorById( |
| 1142 | "msg.arraylength.too.big", String.valueOf(llength)); |
| 1143 | } |
| 1144 | // copy the JS array into a working array, so it can be |
| 1145 | // sorted cheaply. |
| 1146 | final Object[] working = new Object[length]; |
| 1147 | for (int i = 0; i != length; ++i) { |
| 1148 | working[i] = getRawElem(o, i); |
| 1149 | } |
| 1150 | |
| 1151 | // Java's 'Arrays.sort' is guaranteed to be stable so we can use it; however, |
| 1152 | // if the comparator is not consistent, it throws an IllegalArgumentException. |
| 1153 | // In case where the comparator is not consistent, the ECMAScript specification states |
| 1154 | // that sort order is implementation-defined, so we can just return the original array. |
| 1155 | try { |
| 1156 | Arrays.sort(working, comparator); |
| 1157 | } catch (IllegalArgumentException e) { |
| 1158 | return o; |
| 1159 | } |
| 1160 | |
| 1161 | // copy the working array back into thisObj |
| 1162 | for (int i = 0; i < length; ++i) { |
| 1163 | setRawElem(cx, o, i, working[i]); |
| 1164 | } |
| 1165 | |
| 1166 | return o; |
| 1167 | } |
| 1168 | |
| 1169 | private static Object js_push( |
| 1170 | Context cx, JSFunction f, Object nt, VarScope s, Object thisObj, Object[] args) { |