| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 (function(global, utils, extrasUtils) { | 5 (function(global, utils, extrasUtils) { |
| 6 | 6 |
| 7 "use strict"; | 7 "use strict"; |
| 8 | 8 |
| 9 %CheckIsBootstrapping(); | 9 %CheckIsBootstrapping(); |
| 10 | 10 |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 array[key] = new_array[key]; | 321 array[key] = new_array[key]; |
| 322 } | 322 } |
| 323 } | 323 } |
| 324 } | 324 } |
| 325 | 325 |
| 326 | 326 |
| 327 // This is part of the old simple-minded splice. We are using it either | 327 // This is part of the old simple-minded splice. We are using it either |
| 328 // because the receiver is not an array (so we have no choice) or because we | 328 // because the receiver is not an array (so we have no choice) or because we |
| 329 // know we are not deleting or moving a lot of elements. | 329 // know we are not deleting or moving a lot of elements. |
| 330 function SimpleSlice(array, start_i, del_count, len, deleted_elements) { | 330 function SimpleSlice(array, start_i, del_count, len, deleted_elements) { |
| 331 var is_array = IS_ARRAY(array); | |
| 332 for (var i = 0; i < del_count; i++) { | 331 for (var i = 0; i < del_count; i++) { |
| 333 var index = start_i + i; | 332 var index = start_i + i; |
| 334 if (HAS_INDEX(array, index, is_array)) { | 333 if (HAS_INDEX(array, index)) { |
| 335 var current = array[index]; | 334 var current = array[index]; |
| 336 %CreateDataProperty(deleted_elements, i, current); | 335 %CreateDataProperty(deleted_elements, i, current); |
| 337 } | 336 } |
| 338 } | 337 } |
| 339 } | 338 } |
| 340 | 339 |
| 341 | 340 |
| 342 function SimpleMove(array, start_i, del_count, len, num_additional_args) { | 341 function SimpleMove(array, start_i, del_count, len, num_additional_args) { |
| 343 var is_array = IS_ARRAY(array); | |
| 344 if (num_additional_args !== del_count) { | 342 if (num_additional_args !== del_count) { |
| 345 // Move the existing elements after the elements to be deleted | 343 // Move the existing elements after the elements to be deleted |
| 346 // to the right position in the resulting array. | 344 // to the right position in the resulting array. |
| 347 if (num_additional_args > del_count) { | 345 if (num_additional_args > del_count) { |
| 348 for (var i = len - del_count; i > start_i; i--) { | 346 for (var i = len - del_count; i > start_i; i--) { |
| 349 var from_index = i + del_count - 1; | 347 var from_index = i + del_count - 1; |
| 350 var to_index = i + num_additional_args - 1; | 348 var to_index = i + num_additional_args - 1; |
| 351 if (HAS_INDEX(array, from_index, is_array)) { | 349 if (HAS_INDEX(array, from_index)) { |
| 352 array[to_index] = array[from_index]; | 350 array[to_index] = array[from_index]; |
| 353 } else { | 351 } else { |
| 354 delete array[to_index]; | 352 delete array[to_index]; |
| 355 } | 353 } |
| 356 } | 354 } |
| 357 } else { | 355 } else { |
| 358 for (var i = start_i; i < len - del_count; i++) { | 356 for (var i = start_i; i < len - del_count; i++) { |
| 359 var from_index = i + del_count; | 357 var from_index = i + del_count; |
| 360 var to_index = i + num_additional_args; | 358 var to_index = i + num_additional_args; |
| 361 if (HAS_INDEX(array, from_index, is_array)) { | 359 if (HAS_INDEX(array, from_index)) { |
| 362 array[to_index] = array[from_index]; | 360 array[to_index] = array[from_index]; |
| 363 } else { | 361 } else { |
| 364 delete array[to_index]; | 362 delete array[to_index]; |
| 365 } | 363 } |
| 366 } | 364 } |
| 367 for (var i = len; i > len - del_count + num_additional_args; i--) { | 365 for (var i = len; i > len - del_count + num_additional_args; i--) { |
| 368 delete array[i - 1]; | 366 delete array[i - 1]; |
| 369 } | 367 } |
| 370 } | 368 } |
| 371 } | 369 } |
| (...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1048 var length = TO_LENGTH(array.length); | 1046 var length = TO_LENGTH(array.length); |
| 1049 return InnerArraySort(array, length, comparefn); | 1047 return InnerArraySort(array, length, comparefn); |
| 1050 } | 1048 } |
| 1051 | 1049 |
| 1052 | 1050 |
| 1053 // The following functions cannot be made efficient on sparse arrays while | 1051 // The following functions cannot be made efficient on sparse arrays while |
| 1054 // preserving the semantics, since the calls to the receiver function can add | 1052 // preserving the semantics, since the calls to the receiver function can add |
| 1055 // or delete elements from the array. | 1053 // or delete elements from the array. |
| 1056 function InnerArrayFilter(f, receiver, array, length, result) { | 1054 function InnerArrayFilter(f, receiver, array, length, result) { |
| 1057 var result_length = 0; | 1055 var result_length = 0; |
| 1058 var is_array = IS_ARRAY(array); | |
| 1059 for (var i = 0; i < length; i++) { | 1056 for (var i = 0; i < length; i++) { |
| 1060 if (HAS_INDEX(array, i, is_array)) { | 1057 if (HAS_INDEX(array, i)) { |
| 1061 var element = array[i]; | 1058 var element = array[i]; |
| 1062 if (%_Call(f, receiver, element, i, array)) { | 1059 if (%_Call(f, receiver, element, i, array)) { |
| 1063 %CreateDataProperty(result, result_length, element); | 1060 %CreateDataProperty(result, result_length, element); |
| 1064 result_length++; | 1061 result_length++; |
| 1065 } | 1062 } |
| 1066 } | 1063 } |
| 1067 } | 1064 } |
| 1068 return result; | 1065 return result; |
| 1069 } | 1066 } |
| 1070 | 1067 |
| 1071 | 1068 |
| 1072 | 1069 |
| 1073 function ArrayFilter(f, receiver) { | 1070 function ArrayFilter(f, receiver) { |
| 1074 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.filter"); | 1071 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.filter"); |
| 1075 | 1072 |
| 1076 // Pull out the length so that modifications to the length in the | 1073 // Pull out the length so that modifications to the length in the |
| 1077 // loop will not affect the looping and side effects are visible. | 1074 // loop will not affect the looping and side effects are visible. |
| 1078 var array = TO_OBJECT(this); | 1075 var array = TO_OBJECT(this); |
| 1079 var length = TO_LENGTH(array.length); | 1076 var length = TO_LENGTH(array.length); |
| 1080 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); | 1077 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); |
| 1081 var result = ArraySpeciesCreate(array, 0); | 1078 var result = ArraySpeciesCreate(array, 0); |
| 1082 return InnerArrayFilter(f, receiver, array, length, result); | 1079 return InnerArrayFilter(f, receiver, array, length, result); |
| 1083 } | 1080 } |
| 1084 | 1081 |
| 1085 | 1082 |
| 1086 function InnerArrayForEach(f, receiver, array, length) { | 1083 function InnerArrayForEach(f, receiver, array, length) { |
| 1087 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); | 1084 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); |
| 1088 | 1085 |
| 1089 var is_array = IS_ARRAY(array); | |
| 1090 if (IS_UNDEFINED(receiver)) { | 1086 if (IS_UNDEFINED(receiver)) { |
| 1091 for (var i = 0; i < length; i++) { | 1087 for (var i = 0; i < length; i++) { |
| 1092 if (HAS_INDEX(array, i, is_array)) { | 1088 if (HAS_INDEX(array, i)) { |
| 1093 var element = array[i]; | 1089 var element = array[i]; |
| 1094 f(element, i, array); | 1090 f(element, i, array); |
| 1095 } | 1091 } |
| 1096 } | 1092 } |
| 1097 } else { | 1093 } else { |
| 1098 for (var i = 0; i < length; i++) { | 1094 for (var i = 0; i < length; i++) { |
| 1099 if (HAS_INDEX(array, i, is_array)) { | 1095 if (HAS_INDEX(array, i)) { |
| 1100 var element = array[i]; | 1096 var element = array[i]; |
| 1101 %_Call(f, receiver, element, i, array); | 1097 %_Call(f, receiver, element, i, array); |
| 1102 } | 1098 } |
| 1103 } | 1099 } |
| 1104 } | 1100 } |
| 1105 } | 1101 } |
| 1106 | 1102 |
| 1107 | 1103 |
| 1108 function ArrayForEach(f, receiver) { | 1104 function ArrayForEach(f, receiver) { |
| 1109 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.forEach"); | 1105 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.forEach"); |
| 1110 | 1106 |
| 1111 // Pull out the length so that modifications to the length in the | 1107 // Pull out the length so that modifications to the length in the |
| 1112 // loop will not affect the looping and side effects are visible. | 1108 // loop will not affect the looping and side effects are visible. |
| 1113 var array = TO_OBJECT(this); | 1109 var array = TO_OBJECT(this); |
| 1114 var length = TO_LENGTH(array.length); | 1110 var length = TO_LENGTH(array.length); |
| 1115 InnerArrayForEach(f, receiver, array, length); | 1111 InnerArrayForEach(f, receiver, array, length); |
| 1116 } | 1112 } |
| 1117 | 1113 |
| 1118 | 1114 |
| 1119 function InnerArraySome(f, receiver, array, length) { | 1115 function InnerArraySome(f, receiver, array, length) { |
| 1120 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); | 1116 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); |
| 1121 | 1117 |
| 1122 var is_array = IS_ARRAY(array); | |
| 1123 for (var i = 0; i < length; i++) { | 1118 for (var i = 0; i < length; i++) { |
| 1124 if (HAS_INDEX(array, i, is_array)) { | 1119 if (HAS_INDEX(array, i)) { |
| 1125 var element = array[i]; | 1120 var element = array[i]; |
| 1126 if (%_Call(f, receiver, element, i, array)) return true; | 1121 if (%_Call(f, receiver, element, i, array)) return true; |
| 1127 } | 1122 } |
| 1128 } | 1123 } |
| 1129 return false; | 1124 return false; |
| 1130 } | 1125 } |
| 1131 | 1126 |
| 1132 | 1127 |
| 1133 // Executes the function once for each element present in the | 1128 // Executes the function once for each element present in the |
| 1134 // array until it finds one where callback returns true. | 1129 // array until it finds one where callback returns true. |
| 1135 function ArraySome(f, receiver) { | 1130 function ArraySome(f, receiver) { |
| 1136 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.some"); | 1131 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.some"); |
| 1137 | 1132 |
| 1138 // Pull out the length so that modifications to the length in the | 1133 // Pull out the length so that modifications to the length in the |
| 1139 // loop will not affect the looping and side effects are visible. | 1134 // loop will not affect the looping and side effects are visible. |
| 1140 var array = TO_OBJECT(this); | 1135 var array = TO_OBJECT(this); |
| 1141 var length = TO_LENGTH(array.length); | 1136 var length = TO_LENGTH(array.length); |
| 1142 return InnerArraySome(f, receiver, array, length); | 1137 return InnerArraySome(f, receiver, array, length); |
| 1143 } | 1138 } |
| 1144 | 1139 |
| 1145 | 1140 |
| 1146 function InnerArrayEvery(f, receiver, array, length) { | 1141 function InnerArrayEvery(f, receiver, array, length) { |
| 1147 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); | 1142 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); |
| 1148 | 1143 |
| 1149 var is_array = IS_ARRAY(array); | |
| 1150 for (var i = 0; i < length; i++) { | 1144 for (var i = 0; i < length; i++) { |
| 1151 if (HAS_INDEX(array, i, is_array)) { | 1145 if (HAS_INDEX(array, i)) { |
| 1152 var element = array[i]; | 1146 var element = array[i]; |
| 1153 if (!%_Call(f, receiver, element, i, array)) return false; | 1147 if (!%_Call(f, receiver, element, i, array)) return false; |
| 1154 } | 1148 } |
| 1155 } | 1149 } |
| 1156 return true; | 1150 return true; |
| 1157 } | 1151 } |
| 1158 | 1152 |
| 1159 function ArrayEvery(f, receiver) { | 1153 function ArrayEvery(f, receiver) { |
| 1160 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.every"); | 1154 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.every"); |
| 1161 | 1155 |
| 1162 // Pull out the length so that modifications to the length in the | 1156 // Pull out the length so that modifications to the length in the |
| 1163 // loop will not affect the looping and side effects are visible. | 1157 // loop will not affect the looping and side effects are visible. |
| 1164 var array = TO_OBJECT(this); | 1158 var array = TO_OBJECT(this); |
| 1165 var length = TO_LENGTH(array.length); | 1159 var length = TO_LENGTH(array.length); |
| 1166 return InnerArrayEvery(f, receiver, array, length); | 1160 return InnerArrayEvery(f, receiver, array, length); |
| 1167 } | 1161 } |
| 1168 | 1162 |
| 1169 | 1163 |
| 1170 function ArrayMap(f, receiver) { | 1164 function ArrayMap(f, receiver) { |
| 1171 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.map"); | 1165 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.map"); |
| 1172 | 1166 |
| 1173 // Pull out the length so that modifications to the length in the | 1167 // Pull out the length so that modifications to the length in the |
| 1174 // loop will not affect the looping and side effects are visible. | 1168 // loop will not affect the looping and side effects are visible. |
| 1175 var array = TO_OBJECT(this); | 1169 var array = TO_OBJECT(this); |
| 1176 var length = TO_LENGTH(array.length); | 1170 var length = TO_LENGTH(array.length); |
| 1177 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); | 1171 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); |
| 1178 var result = ArraySpeciesCreate(array, length); | 1172 var result = ArraySpeciesCreate(array, length); |
| 1179 var is_array = IS_ARRAY(array); | |
| 1180 for (var i = 0; i < length; i++) { | 1173 for (var i = 0; i < length; i++) { |
| 1181 if (HAS_INDEX(array, i, is_array)) { | 1174 if (HAS_INDEX(array, i)) { |
| 1182 var element = array[i]; | 1175 var element = array[i]; |
| 1183 %CreateDataProperty(result, i, %_Call(f, receiver, element, i, array)); | 1176 %CreateDataProperty(result, i, %_Call(f, receiver, element, i, array)); |
| 1184 } | 1177 } |
| 1185 } | 1178 } |
| 1186 return result; | 1179 return result; |
| 1187 } | 1180 } |
| 1188 | 1181 |
| 1189 | 1182 |
| 1190 // For .indexOf, we don't need to pass in the number of arguments | 1183 // For .indexOf, we don't need to pass in the number of arguments |
| 1191 // at the callsite since ToInteger(undefined) == 0; however, for | 1184 // at the callsite since ToInteger(undefined) == 0; however, for |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1310 return InnerArrayLastIndexOf(this, element, index, length, | 1303 return InnerArrayLastIndexOf(this, element, index, length, |
| 1311 arguments.length); | 1304 arguments.length); |
| 1312 } | 1305 } |
| 1313 | 1306 |
| 1314 | 1307 |
| 1315 function InnerArrayReduce(callback, current, array, length, argumentsLength) { | 1308 function InnerArrayReduce(callback, current, array, length, argumentsLength) { |
| 1316 if (!IS_CALLABLE(callback)) { | 1309 if (!IS_CALLABLE(callback)) { |
| 1317 throw MakeTypeError(kCalledNonCallable, callback); | 1310 throw MakeTypeError(kCalledNonCallable, callback); |
| 1318 } | 1311 } |
| 1319 | 1312 |
| 1320 var is_array = IS_ARRAY(array); | |
| 1321 var i = 0; | 1313 var i = 0; |
| 1322 find_initial: if (argumentsLength < 2) { | 1314 find_initial: if (argumentsLength < 2) { |
| 1323 for (; i < length; i++) { | 1315 for (; i < length; i++) { |
| 1324 if (HAS_INDEX(array, i, is_array)) { | 1316 if (HAS_INDEX(array, i)) { |
| 1325 current = array[i++]; | 1317 current = array[i++]; |
| 1326 break find_initial; | 1318 break find_initial; |
| 1327 } | 1319 } |
| 1328 } | 1320 } |
| 1329 throw MakeTypeError(kReduceNoInitial); | 1321 throw MakeTypeError(kReduceNoInitial); |
| 1330 } | 1322 } |
| 1331 | 1323 |
| 1332 for (; i < length; i++) { | 1324 for (; i < length; i++) { |
| 1333 if (HAS_INDEX(array, i, is_array)) { | 1325 if (HAS_INDEX(array, i)) { |
| 1334 var element = array[i]; | 1326 var element = array[i]; |
| 1335 current = callback(current, element, i, array); | 1327 current = callback(current, element, i, array); |
| 1336 } | 1328 } |
| 1337 } | 1329 } |
| 1338 return current; | 1330 return current; |
| 1339 } | 1331 } |
| 1340 | 1332 |
| 1341 | 1333 |
| 1342 function ArrayReduce(callback, current) { | 1334 function ArrayReduce(callback, current) { |
| 1343 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduce"); | 1335 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduce"); |
| 1344 | 1336 |
| 1345 // Pull out the length so that modifications to the length in the | 1337 // Pull out the length so that modifications to the length in the |
| 1346 // loop will not affect the looping and side effects are visible. | 1338 // loop will not affect the looping and side effects are visible. |
| 1347 var array = TO_OBJECT(this); | 1339 var array = TO_OBJECT(this); |
| 1348 var length = TO_LENGTH(array.length); | 1340 var length = TO_LENGTH(array.length); |
| 1349 return InnerArrayReduce(callback, current, array, length, | 1341 return InnerArrayReduce(callback, current, array, length, |
| 1350 arguments.length); | 1342 arguments.length); |
| 1351 } | 1343 } |
| 1352 | 1344 |
| 1353 | 1345 |
| 1354 function InnerArrayReduceRight(callback, current, array, length, | 1346 function InnerArrayReduceRight(callback, current, array, length, |
| 1355 argumentsLength) { | 1347 argumentsLength) { |
| 1356 if (!IS_CALLABLE(callback)) { | 1348 if (!IS_CALLABLE(callback)) { |
| 1357 throw MakeTypeError(kCalledNonCallable, callback); | 1349 throw MakeTypeError(kCalledNonCallable, callback); |
| 1358 } | 1350 } |
| 1359 | 1351 |
| 1360 var is_array = IS_ARRAY(array); | |
| 1361 var i = length - 1; | 1352 var i = length - 1; |
| 1362 find_initial: if (argumentsLength < 2) { | 1353 find_initial: if (argumentsLength < 2) { |
| 1363 for (; i >= 0; i--) { | 1354 for (; i >= 0; i--) { |
| 1364 if (HAS_INDEX(array, i, is_array)) { | 1355 if (HAS_INDEX(array, i)) { |
| 1365 current = array[i--]; | 1356 current = array[i--]; |
| 1366 break find_initial; | 1357 break find_initial; |
| 1367 } | 1358 } |
| 1368 } | 1359 } |
| 1369 throw MakeTypeError(kReduceNoInitial); | 1360 throw MakeTypeError(kReduceNoInitial); |
| 1370 } | 1361 } |
| 1371 | 1362 |
| 1372 for (; i >= 0; i--) { | 1363 for (; i >= 0; i--) { |
| 1373 if (HAS_INDEX(array, i, is_array)) { | 1364 if (HAS_INDEX(array, i)) { |
| 1374 var element = array[i]; | 1365 var element = array[i]; |
| 1375 current = callback(current, element, i, array); | 1366 current = callback(current, element, i, array); |
| 1376 } | 1367 } |
| 1377 } | 1368 } |
| 1378 return current; | 1369 return current; |
| 1379 } | 1370 } |
| 1380 | 1371 |
| 1381 | 1372 |
| 1382 function ArrayReduceRight(callback, current) { | 1373 function ArrayReduceRight(callback, current) { |
| 1383 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduceRight"); | 1374 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduceRight"); |
| (...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1789 %InstallToContext([ | 1780 %InstallToContext([ |
| 1790 "array_pop", ArrayPop, | 1781 "array_pop", ArrayPop, |
| 1791 "array_push", ArrayPush, | 1782 "array_push", ArrayPush, |
| 1792 "array_shift", ArrayShift, | 1783 "array_shift", ArrayShift, |
| 1793 "array_splice", ArraySplice, | 1784 "array_splice", ArraySplice, |
| 1794 "array_slice", ArraySlice, | 1785 "array_slice", ArraySlice, |
| 1795 "array_unshift", ArrayUnshift, | 1786 "array_unshift", ArrayUnshift, |
| 1796 ]); | 1787 ]); |
| 1797 | 1788 |
| 1798 }); | 1789 }); |
| OLD | NEW |