OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 985 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
996 | 996 |
997 // The following functions cannot be made efficient on sparse arrays while | 997 // The following functions cannot be made efficient on sparse arrays while |
998 // preserving the semantics, since the calls to the receiver function can add | 998 // preserving the semantics, since the calls to the receiver function can add |
999 // or delete elements from the array. | 999 // or delete elements from the array. |
1000 function ArrayFilter(f, receiver) { | 1000 function ArrayFilter(f, receiver) { |
1001 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | 1001 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { |
1002 throw MakeTypeError("called_on_null_or_undefined", | 1002 throw MakeTypeError("called_on_null_or_undefined", |
1003 ["Array.prototype.filter"]); | 1003 ["Array.prototype.filter"]); |
1004 } | 1004 } |
1005 | 1005 |
| 1006 // Pull out the length so that modifications to the length in the |
| 1007 // loop will not affect the looping and side effects are visible. |
| 1008 var array = ToObject(this); |
| 1009 var length = ToUint32(array.length); |
| 1010 |
1006 if (!IS_SPEC_FUNCTION(f)) { | 1011 if (!IS_SPEC_FUNCTION(f)) { |
1007 throw MakeTypeError('called_non_callable', [ f ]); | 1012 throw MakeTypeError('called_non_callable', [ f ]); |
1008 } | 1013 } |
1009 if (IS_NULL_OR_UNDEFINED(receiver)) { | 1014 if (IS_NULL_OR_UNDEFINED(receiver)) { |
1010 receiver = %GetDefaultReceiver(f) || receiver; | 1015 receiver = %GetDefaultReceiver(f) || receiver; |
1011 } | 1016 } |
1012 // Pull out the length so that modifications to the length in the | 1017 |
1013 // loop will not affect the looping. | |
1014 var length = ToUint32(this.length); | |
1015 var result = []; | 1018 var result = []; |
1016 var result_length = 0; | 1019 var result_length = 0; |
1017 for (var i = 0; i < length; i++) { | 1020 for (var i = 0; i < length; i++) { |
1018 var current = this[i]; | 1021 var current = array[i]; |
1019 if (!IS_UNDEFINED(current) || i in this) { | 1022 if (!IS_UNDEFINED(current) || i in array) { |
1020 if (%_CallFunction(receiver, current, i, this, f)) { | 1023 if (%_CallFunction(receiver, current, i, array, f)) { |
1021 result[result_length++] = current; | 1024 result[result_length++] = current; |
1022 } | 1025 } |
1023 } | 1026 } |
1024 } | 1027 } |
1025 return result; | 1028 return result; |
1026 } | 1029 } |
1027 | 1030 |
1028 | 1031 |
1029 function ArrayForEach(f, receiver) { | 1032 function ArrayForEach(f, receiver) { |
1030 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | 1033 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { |
1031 throw MakeTypeError("called_on_null_or_undefined", | 1034 throw MakeTypeError("called_on_null_or_undefined", |
1032 ["Array.prototype.forEach"]); | 1035 ["Array.prototype.forEach"]); |
1033 } | 1036 } |
1034 | 1037 |
| 1038 // Pull out the length so that modifications to the length in the |
| 1039 // loop will not affect the looping and side effects are visible. |
| 1040 var array = ToObject(this); |
| 1041 var length = TO_UINT32(array.length); |
| 1042 |
1035 if (!IS_SPEC_FUNCTION(f)) { | 1043 if (!IS_SPEC_FUNCTION(f)) { |
1036 throw MakeTypeError('called_non_callable', [ f ]); | 1044 throw MakeTypeError('called_non_callable', [ f ]); |
1037 } | 1045 } |
1038 if (IS_NULL_OR_UNDEFINED(receiver)) { | 1046 if (IS_NULL_OR_UNDEFINED(receiver)) { |
1039 receiver = %GetDefaultReceiver(f) || receiver; | 1047 receiver = %GetDefaultReceiver(f) || receiver; |
1040 } | 1048 } |
1041 // Pull out the length so that modifications to the length in the | 1049 |
1042 // loop will not affect the looping. | |
1043 var length = TO_UINT32(this.length); | |
1044 for (var i = 0; i < length; i++) { | 1050 for (var i = 0; i < length; i++) { |
1045 var current = this[i]; | 1051 var current = array[i]; |
1046 if (!IS_UNDEFINED(current) || i in this) { | 1052 if (!IS_UNDEFINED(current) || i in array) { |
1047 %_CallFunction(receiver, current, i, this, f); | 1053 %_CallFunction(receiver, current, i, array, f); |
1048 } | 1054 } |
1049 } | 1055 } |
1050 } | 1056 } |
1051 | 1057 |
1052 | 1058 |
1053 // Executes the function once for each element present in the | 1059 // Executes the function once for each element present in the |
1054 // array until it finds one where callback returns true. | 1060 // array until it finds one where callback returns true. |
1055 function ArraySome(f, receiver) { | 1061 function ArraySome(f, receiver) { |
1056 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | 1062 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { |
1057 throw MakeTypeError("called_on_null_or_undefined", | 1063 throw MakeTypeError("called_on_null_or_undefined", |
1058 ["Array.prototype.some"]); | 1064 ["Array.prototype.some"]); |
1059 } | 1065 } |
1060 | 1066 |
| 1067 // Pull out the length so that modifications to the length in the |
| 1068 // loop will not affect the looping and side effects are visible. |
| 1069 var array = ToObject(this); |
| 1070 var length = TO_UINT32(array.length); |
| 1071 |
1061 if (!IS_SPEC_FUNCTION(f)) { | 1072 if (!IS_SPEC_FUNCTION(f)) { |
1062 throw MakeTypeError('called_non_callable', [ f ]); | 1073 throw MakeTypeError('called_non_callable', [ f ]); |
1063 } | 1074 } |
1064 if (IS_NULL_OR_UNDEFINED(receiver)) { | 1075 if (IS_NULL_OR_UNDEFINED(receiver)) { |
1065 receiver = %GetDefaultReceiver(f) || receiver; | 1076 receiver = %GetDefaultReceiver(f) || receiver; |
1066 } | 1077 } |
1067 // Pull out the length so that modifications to the length in the | 1078 |
1068 // loop will not affect the looping. | |
1069 var length = TO_UINT32(this.length); | |
1070 for (var i = 0; i < length; i++) { | 1079 for (var i = 0; i < length; i++) { |
1071 var current = this[i]; | 1080 var current = array[i]; |
1072 if (!IS_UNDEFINED(current) || i in this) { | 1081 if (!IS_UNDEFINED(current) || i in array) { |
1073 if (%_CallFunction(receiver, current, i, this, f)) return true; | 1082 if (%_CallFunction(receiver, current, i, array, f)) return true; |
1074 } | 1083 } |
1075 } | 1084 } |
1076 return false; | 1085 return false; |
1077 } | 1086 } |
1078 | 1087 |
1079 | 1088 |
1080 function ArrayEvery(f, receiver) { | 1089 function ArrayEvery(f, receiver) { |
1081 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | 1090 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { |
1082 throw MakeTypeError("called_on_null_or_undefined", | 1091 throw MakeTypeError("called_on_null_or_undefined", |
1083 ["Array.prototype.every"]); | 1092 ["Array.prototype.every"]); |
1084 } | 1093 } |
1085 | 1094 |
| 1095 // Pull out the length so that modifications to the length in the |
| 1096 // loop will not affect the looping and side effects are visible. |
| 1097 var array = ToObject(this); |
| 1098 var length = TO_UINT32(array.length); |
| 1099 |
1086 if (!IS_SPEC_FUNCTION(f)) { | 1100 if (!IS_SPEC_FUNCTION(f)) { |
1087 throw MakeTypeError('called_non_callable', [ f ]); | 1101 throw MakeTypeError('called_non_callable', [ f ]); |
1088 } | 1102 } |
1089 if (IS_NULL_OR_UNDEFINED(receiver)) { | 1103 if (IS_NULL_OR_UNDEFINED(receiver)) { |
1090 receiver = %GetDefaultReceiver(f) || receiver; | 1104 receiver = %GetDefaultReceiver(f) || receiver; |
1091 } | 1105 } |
1092 // Pull out the length so that modifications to the length in the | 1106 |
1093 // loop will not affect the looping. | |
1094 var length = TO_UINT32(this.length); | |
1095 for (var i = 0; i < length; i++) { | 1107 for (var i = 0; i < length; i++) { |
1096 var current = this[i]; | 1108 var current = array[i]; |
1097 if (!IS_UNDEFINED(current) || i in this) { | 1109 if (!IS_UNDEFINED(current) || i in array) { |
1098 if (!%_CallFunction(receiver, current, i, this, f)) return false; | 1110 if (!%_CallFunction(receiver, current, i, array, f)) return false; |
1099 } | 1111 } |
1100 } | 1112 } |
1101 return true; | 1113 return true; |
1102 } | 1114 } |
1103 | 1115 |
1104 function ArrayMap(f, receiver) { | 1116 function ArrayMap(f, receiver) { |
1105 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | 1117 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { |
1106 throw MakeTypeError("called_on_null_or_undefined", | 1118 throw MakeTypeError("called_on_null_or_undefined", |
1107 ["Array.prototype.map"]); | 1119 ["Array.prototype.map"]); |
1108 } | 1120 } |
1109 | 1121 |
| 1122 // Pull out the length so that modifications to the length in the |
| 1123 // loop will not affect the looping and side effects are visible. |
| 1124 var array = ToObject(this); |
| 1125 var length = TO_UINT32(array.length); |
| 1126 |
1110 if (!IS_SPEC_FUNCTION(f)) { | 1127 if (!IS_SPEC_FUNCTION(f)) { |
1111 throw MakeTypeError('called_non_callable', [ f ]); | 1128 throw MakeTypeError('called_non_callable', [ f ]); |
1112 } | 1129 } |
1113 if (IS_NULL_OR_UNDEFINED(receiver)) { | 1130 if (IS_NULL_OR_UNDEFINED(receiver)) { |
1114 receiver = %GetDefaultReceiver(f) || receiver; | 1131 receiver = %GetDefaultReceiver(f) || receiver; |
1115 } | 1132 } |
1116 // Pull out the length so that modifications to the length in the | 1133 |
1117 // loop will not affect the looping. | |
1118 var length = TO_UINT32(this.length); | |
1119 var result = new $Array(); | 1134 var result = new $Array(); |
1120 var accumulator = new InternalArray(length); | 1135 var accumulator = new InternalArray(length); |
1121 for (var i = 0; i < length; i++) { | 1136 for (var i = 0; i < length; i++) { |
1122 var current = this[i]; | 1137 var current = array[i]; |
1123 if (!IS_UNDEFINED(current) || i in this) { | 1138 if (!IS_UNDEFINED(current) || i in array) { |
1124 accumulator[i] = %_CallFunction(receiver, current, i, this, f); | 1139 accumulator[i] = %_CallFunction(receiver, current, i, array, f); |
1125 } | 1140 } |
1126 } | 1141 } |
1127 %MoveArrayContents(accumulator, result); | 1142 %MoveArrayContents(accumulator, result); |
1128 return result; | 1143 return result; |
1129 } | 1144 } |
1130 | 1145 |
1131 | 1146 |
1132 function ArrayIndexOf(element, index) { | 1147 function ArrayIndexOf(element, index) { |
1133 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | 1148 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { |
1134 throw MakeTypeError("called_on_null_or_undefined", | 1149 throw MakeTypeError("called_on_null_or_undefined", |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1248 return -1; | 1263 return -1; |
1249 } | 1264 } |
1250 | 1265 |
1251 | 1266 |
1252 function ArrayReduce(callback, current) { | 1267 function ArrayReduce(callback, current) { |
1253 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | 1268 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { |
1254 throw MakeTypeError("called_on_null_or_undefined", | 1269 throw MakeTypeError("called_on_null_or_undefined", |
1255 ["Array.prototype.reduce"]); | 1270 ["Array.prototype.reduce"]); |
1256 } | 1271 } |
1257 | 1272 |
| 1273 // Pull out the length so that modifications to the length in the |
| 1274 // loop will not affect the looping and side effects are visible. |
| 1275 var array = ToObject(this); |
| 1276 var length = ToUint32(array.length); |
| 1277 |
1258 if (!IS_SPEC_FUNCTION(callback)) { | 1278 if (!IS_SPEC_FUNCTION(callback)) { |
1259 throw MakeTypeError('called_non_callable', [callback]); | 1279 throw MakeTypeError('called_non_callable', [callback]); |
1260 } | 1280 } |
1261 | 1281 |
1262 // Pull out the length so that modifications to the length in the | |
1263 // loop will not affect the looping. | |
1264 var length = ToUint32(this.length); | |
1265 var i = 0; | 1282 var i = 0; |
1266 | |
1267 find_initial: if (%_ArgumentsLength() < 2) { | 1283 find_initial: if (%_ArgumentsLength() < 2) { |
1268 for (; i < length; i++) { | 1284 for (; i < length; i++) { |
1269 current = this[i]; | 1285 current = array[i]; |
1270 if (!IS_UNDEFINED(current) || i in this) { | 1286 if (!IS_UNDEFINED(current) || i in array) { |
1271 i++; | 1287 i++; |
1272 break find_initial; | 1288 break find_initial; |
1273 } | 1289 } |
1274 } | 1290 } |
1275 throw MakeTypeError('reduce_no_initial', []); | 1291 throw MakeTypeError('reduce_no_initial', []); |
1276 } | 1292 } |
1277 | 1293 |
1278 var receiver = %GetDefaultReceiver(callback); | 1294 var receiver = %GetDefaultReceiver(callback); |
1279 for (; i < length; i++) { | 1295 for (; i < length; i++) { |
1280 var element = this[i]; | 1296 var element = array[i]; |
1281 if (!IS_UNDEFINED(element) || i in this) { | 1297 if (!IS_UNDEFINED(element) || i in array) { |
1282 current = %_CallFunction(receiver, current, element, i, this, callback); | 1298 current = %_CallFunction(receiver, current, element, i, array, callback); |
1283 } | 1299 } |
1284 } | 1300 } |
1285 return current; | 1301 return current; |
1286 } | 1302 } |
1287 | 1303 |
1288 function ArrayReduceRight(callback, current) { | 1304 function ArrayReduceRight(callback, current) { |
1289 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | 1305 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { |
1290 throw MakeTypeError("called_on_null_or_undefined", | 1306 throw MakeTypeError("called_on_null_or_undefined", |
1291 ["Array.prototype.reduceRight"]); | 1307 ["Array.prototype.reduceRight"]); |
1292 } | 1308 } |
1293 | 1309 |
| 1310 // Pull out the length so that side effects are visible before the |
| 1311 // callback function is checked. |
| 1312 var array = ToObject(this); |
| 1313 var length = ToUint32(array.length); |
| 1314 |
1294 if (!IS_SPEC_FUNCTION(callback)) { | 1315 if (!IS_SPEC_FUNCTION(callback)) { |
1295 throw MakeTypeError('called_non_callable', [callback]); | 1316 throw MakeTypeError('called_non_callable', [callback]); |
1296 } | 1317 } |
1297 var i = ToUint32(this.length) - 1; | |
1298 | 1318 |
| 1319 var i = length - 1; |
1299 find_initial: if (%_ArgumentsLength() < 2) { | 1320 find_initial: if (%_ArgumentsLength() < 2) { |
1300 for (; i >= 0; i--) { | 1321 for (; i >= 0; i--) { |
1301 current = this[i]; | 1322 current = array[i]; |
1302 if (!IS_UNDEFINED(current) || i in this) { | 1323 if (!IS_UNDEFINED(current) || i in array) { |
1303 i--; | 1324 i--; |
1304 break find_initial; | 1325 break find_initial; |
1305 } | 1326 } |
1306 } | 1327 } |
1307 throw MakeTypeError('reduce_no_initial', []); | 1328 throw MakeTypeError('reduce_no_initial', []); |
1308 } | 1329 } |
1309 | 1330 |
1310 var receiver = %GetDefaultReceiver(callback); | 1331 var receiver = %GetDefaultReceiver(callback); |
1311 for (; i >= 0; i--) { | 1332 for (; i >= 0; i--) { |
1312 var element = this[i]; | 1333 var element = array[i]; |
1313 if (!IS_UNDEFINED(element) || i in this) { | 1334 if (!IS_UNDEFINED(element) || i in array) { |
1314 current = %_CallFunction(receiver, current, element, i, this, callback); | 1335 current = %_CallFunction(receiver, current, element, i, array, callback); |
1315 } | 1336 } |
1316 } | 1337 } |
1317 return current; | 1338 return current; |
1318 } | 1339 } |
1319 | 1340 |
1320 // ES5, 15.4.3.2 | 1341 // ES5, 15.4.3.2 |
1321 function ArrayIsArray(obj) { | 1342 function ArrayIsArray(obj) { |
1322 return IS_ARRAY(obj); | 1343 return IS_ARRAY(obj); |
1323 } | 1344 } |
1324 | 1345 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1382 // exposed to user code. | 1403 // exposed to user code. |
1383 // Adding only the functions that are actually used. | 1404 // Adding only the functions that are actually used. |
1384 SetUpLockedPrototype(InternalArray, $Array(), $Array( | 1405 SetUpLockedPrototype(InternalArray, $Array(), $Array( |
1385 "join", getFunction("join", ArrayJoin), | 1406 "join", getFunction("join", ArrayJoin), |
1386 "pop", getFunction("pop", ArrayPop), | 1407 "pop", getFunction("pop", ArrayPop), |
1387 "push", getFunction("push", ArrayPush) | 1408 "push", getFunction("push", ArrayPush) |
1388 )); | 1409 )); |
1389 } | 1410 } |
1390 | 1411 |
1391 SetUpArray(); | 1412 SetUpArray(); |
OLD | NEW |