Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(601)

Side by Side Diff: src/array.js

Issue 8197002: Fix some array functions to behave as specified. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix order of side effects in some array functions. Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | test/test262/test262.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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();
OLDNEW
« no previous file with comments | « no previous file | test/test262/test262.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698