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

Side by Side Diff: src/array.js

Issue 7776008: Make built-in functions not rely on callback functions .call method. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix bugs in last two functions changed. Created 9 years, 3 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 | no next file » | 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 978 matching lines...) Expand 10 before | Expand all | Expand 10 after
989 // or delete elements from the array. 989 // or delete elements from the array.
990 function ArrayFilter(f, receiver) { 990 function ArrayFilter(f, receiver) {
991 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 991 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
992 throw MakeTypeError("called_on_null_or_undefined", 992 throw MakeTypeError("called_on_null_or_undefined",
993 ["Array.prototype.filter"]); 993 ["Array.prototype.filter"]);
994 } 994 }
995 995
996 if (!IS_FUNCTION(f)) { 996 if (!IS_FUNCTION(f)) {
997 throw MakeTypeError('called_non_callable', [ f ]); 997 throw MakeTypeError('called_non_callable', [ f ]);
998 } 998 }
999 if (IS_NULL_OR_UNDEFINED(receiver)) {
1000 receiver = %GetDefaultReceiver(f) || receiver;
1001 }
999 // Pull out the length so that modifications to the length in the 1002 // Pull out the length so that modifications to the length in the
1000 // loop will not affect the looping. 1003 // loop will not affect the looping.
1001 var length = ToUint32(this.length); 1004 var length = ToUint32(this.length);
1002 var result = []; 1005 var result = [];
1003 var result_length = 0; 1006 var result_length = 0;
1004 for (var i = 0; i < length; i++) { 1007 for (var i = 0; i < length; i++) {
1005 var current = this[i]; 1008 var current = this[i];
1006 if (!IS_UNDEFINED(current) || i in this) { 1009 if (!IS_UNDEFINED(current) || i in this) {
1007 if (f.call(receiver, current, i, this)) { 1010 if (%_CallFunction(receiver, current, i, this, f)) {
1008 result[result_length++] = current; 1011 result[result_length++] = current;
1009 } 1012 }
1010 } 1013 }
1011 } 1014 }
1012 return result; 1015 return result;
1013 } 1016 }
1014 1017
1015 1018
1016 function ArrayForEach(f, receiver) { 1019 function ArrayForEach(f, receiver) {
1017 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 1020 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
1018 throw MakeTypeError("called_on_null_or_undefined", 1021 throw MakeTypeError("called_on_null_or_undefined",
1019 ["Array.prototype.forEach"]); 1022 ["Array.prototype.forEach"]);
1020 } 1023 }
1021 1024
1022 if (!IS_FUNCTION(f)) { 1025 if (!IS_FUNCTION(f)) {
1023 throw MakeTypeError('called_non_callable', [ f ]); 1026 throw MakeTypeError('called_non_callable', [ f ]);
1024 } 1027 }
1028 if (IS_NULL_OR_UNDEFINED(receiver)) {
1029 receiver = %GetDefaultReceiver(f) || receiver;
1030 }
1025 // Pull out the length so that modifications to the length in the 1031 // Pull out the length so that modifications to the length in the
1026 // loop will not affect the looping. 1032 // loop will not affect the looping.
1027 var length = TO_UINT32(this.length); 1033 var length = TO_UINT32(this.length);
1028 for (var i = 0; i < length; i++) { 1034 for (var i = 0; i < length; i++) {
1029 var current = this[i]; 1035 var current = this[i];
1030 if (!IS_UNDEFINED(current) || i in this) { 1036 if (!IS_UNDEFINED(current) || i in this) {
1031 f.call(receiver, current, i, this); 1037 %_CallFunction(receiver, current, i, this, f);
1032 } 1038 }
1033 } 1039 }
1034 } 1040 }
1035 1041
1036 1042
1037 // Executes the function once for each element present in the 1043 // Executes the function once for each element present in the
1038 // array until it finds one where callback returns true. 1044 // array until it finds one where callback returns true.
1039 function ArraySome(f, receiver) { 1045 function ArraySome(f, receiver) {
1040 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 1046 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
1041 throw MakeTypeError("called_on_null_or_undefined", 1047 throw MakeTypeError("called_on_null_or_undefined",
1042 ["Array.prototype.some"]); 1048 ["Array.prototype.some"]);
1043 } 1049 }
1044 1050
1045 if (!IS_FUNCTION(f)) { 1051 if (!IS_FUNCTION(f)) {
1046 throw MakeTypeError('called_non_callable', [ f ]); 1052 throw MakeTypeError('called_non_callable', [ f ]);
1047 } 1053 }
1054 if (IS_NULL_OR_UNDEFINED(receiver)) {
1055 receiver = %GetDefaultReceiver(f) || receiver;
1056 }
1048 // Pull out the length so that modifications to the length in the 1057 // Pull out the length so that modifications to the length in the
1049 // loop will not affect the looping. 1058 // loop will not affect the looping.
1050 var length = TO_UINT32(this.length); 1059 var length = TO_UINT32(this.length);
1051 for (var i = 0; i < length; i++) { 1060 for (var i = 0; i < length; i++) {
1052 var current = this[i]; 1061 var current = this[i];
1053 if (!IS_UNDEFINED(current) || i in this) { 1062 if (!IS_UNDEFINED(current) || i in this) {
1054 if (f.call(receiver, current, i, this)) return true; 1063 if (%_CallFunction(receiver, current, i, this, f)) return true;
1055 } 1064 }
1056 } 1065 }
1057 return false; 1066 return false;
1058 } 1067 }
1059 1068
1060 1069
1061 function ArrayEvery(f, receiver) { 1070 function ArrayEvery(f, receiver) {
1062 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 1071 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
1063 throw MakeTypeError("called_on_null_or_undefined", 1072 throw MakeTypeError("called_on_null_or_undefined",
1064 ["Array.prototype.every"]); 1073 ["Array.prototype.every"]);
1065 } 1074 }
1066 1075
1067 if (!IS_FUNCTION(f)) { 1076 if (!IS_FUNCTION(f)) {
1068 throw MakeTypeError('called_non_callable', [ f ]); 1077 throw MakeTypeError('called_non_callable', [ f ]);
1069 } 1078 }
1079 if (IS_NULL_OR_UNDEFINED(receiver)) {
1080 receiver = %GetDefaultReceiver(f) || receiver;
1081 }
1070 // Pull out the length so that modifications to the length in the 1082 // Pull out the length so that modifications to the length in the
1071 // loop will not affect the looping. 1083 // loop will not affect the looping.
1072 var length = TO_UINT32(this.length); 1084 var length = TO_UINT32(this.length);
1073 for (var i = 0; i < length; i++) { 1085 for (var i = 0; i < length; i++) {
1074 var current = this[i]; 1086 var current = this[i];
1075 if (!IS_UNDEFINED(current) || i in this) { 1087 if (!IS_UNDEFINED(current) || i in this) {
1076 if (!f.call(receiver, current, i, this)) return false; 1088 if (!%_CallFunction(receiver, current, i, this, f)) return false;
1077 } 1089 }
1078 } 1090 }
1079 return true; 1091 return true;
1080 } 1092 }
1081 1093
1082 function ArrayMap(f, receiver) { 1094 function ArrayMap(f, receiver) {
1083 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 1095 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
1084 throw MakeTypeError("called_on_null_or_undefined", 1096 throw MakeTypeError("called_on_null_or_undefined",
1085 ["Array.prototype.map"]); 1097 ["Array.prototype.map"]);
1086 } 1098 }
1087 1099
1088 if (!IS_FUNCTION(f)) { 1100 if (!IS_FUNCTION(f)) {
1089 throw MakeTypeError('called_non_callable', [ f ]); 1101 throw MakeTypeError('called_non_callable', [ f ]);
1090 } 1102 }
1103 if (IS_NULL_OR_UNDEFINED(receiver)) {
1104 receiver = %GetDefaultReceiver(f) || receiver;
1105 }
1091 // Pull out the length so that modifications to the length in the 1106 // Pull out the length so that modifications to the length in the
1092 // loop will not affect the looping. 1107 // loop will not affect the looping.
1093 var length = TO_UINT32(this.length); 1108 var length = TO_UINT32(this.length);
1094 var result = new $Array(); 1109 var result = new $Array();
1095 var accumulator = new InternalArray(length); 1110 var accumulator = new InternalArray(length);
1096 for (var i = 0; i < length; i++) { 1111 for (var i = 0; i < length; i++) {
1097 var current = this[i]; 1112 var current = this[i];
1098 if (!IS_UNDEFINED(current) || i in this) { 1113 if (!IS_UNDEFINED(current) || i in this) {
1099 accumulator[i] = f.call(receiver, current, i, this); 1114 accumulator[i] = %_CallFunction(receiver, current, i, this, f);
1100 } 1115 }
1101 } 1116 }
1102 %MoveArrayContents(accumulator, result); 1117 %MoveArrayContents(accumulator, result);
1103 return result; 1118 return result;
1104 } 1119 }
1105 1120
1106 1121
1107 function ArrayIndexOf(element, index) { 1122 function ArrayIndexOf(element, index) {
1108 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 1123 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
1109 throw MakeTypeError("called_on_null_or_undefined", 1124 throw MakeTypeError("called_on_null_or_undefined",
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1226 1241
1227 function ArrayReduce(callback, current) { 1242 function ArrayReduce(callback, current) {
1228 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 1243 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
1229 throw MakeTypeError("called_on_null_or_undefined", 1244 throw MakeTypeError("called_on_null_or_undefined",
1230 ["Array.prototype.reduce"]); 1245 ["Array.prototype.reduce"]);
1231 } 1246 }
1232 1247
1233 if (!IS_FUNCTION(callback)) { 1248 if (!IS_FUNCTION(callback)) {
1234 throw MakeTypeError('called_non_callable', [callback]); 1249 throw MakeTypeError('called_non_callable', [callback]);
1235 } 1250 }
1251
1236 // Pull out the length so that modifications to the length in the 1252 // Pull out the length so that modifications to the length in the
1237 // loop will not affect the looping. 1253 // loop will not affect the looping.
1238 var length = ToUint32(this.length); 1254 var length = ToUint32(this.length);
1239 var i = 0; 1255 var i = 0;
1240 1256
1241 find_initial: if (%_ArgumentsLength() < 2) { 1257 find_initial: if (%_ArgumentsLength() < 2) {
1242 for (; i < length; i++) { 1258 for (; i < length; i++) {
1243 current = this[i]; 1259 current = this[i];
1244 if (!IS_UNDEFINED(current) || i in this) { 1260 if (!IS_UNDEFINED(current) || i in this) {
1245 i++; 1261 i++;
1246 break find_initial; 1262 break find_initial;
1247 } 1263 }
1248 } 1264 }
1249 throw MakeTypeError('reduce_no_initial', []); 1265 throw MakeTypeError('reduce_no_initial', []);
1250 } 1266 }
1251 1267
1268 var receiver = %GetDefaultReceiver(callback);
1252 for (; i < length; i++) { 1269 for (; i < length; i++) {
1253 var element = this[i]; 1270 var element = this[i];
1254 if (!IS_UNDEFINED(element) || i in this) { 1271 if (!IS_UNDEFINED(element) || i in this) {
1255 current = callback.call(void 0, current, element, i, this); 1272 current = %_CallFunction(receiver, current, element, i, this, callback);
1256 } 1273 }
1257 } 1274 }
1258 return current; 1275 return current;
1259 } 1276 }
1260 1277
1261 function ArrayReduceRight(callback, current) { 1278 function ArrayReduceRight(callback, current) {
1262 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 1279 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
1263 throw MakeTypeError("called_on_null_or_undefined", 1280 throw MakeTypeError("called_on_null_or_undefined",
1264 ["Array.prototype.reduceRight"]); 1281 ["Array.prototype.reduceRight"]);
1265 } 1282 }
1266 1283
1267 if (!IS_FUNCTION(callback)) { 1284 if (!IS_FUNCTION(callback)) {
1268 throw MakeTypeError('called_non_callable', [callback]); 1285 throw MakeTypeError('called_non_callable', [callback]);
1269 } 1286 }
1270 var i = ToUint32(this.length) - 1; 1287 var i = ToUint32(this.length) - 1;
1271 1288
1272 find_initial: if (%_ArgumentsLength() < 2) { 1289 find_initial: if (%_ArgumentsLength() < 2) {
1273 for (; i >= 0; i--) { 1290 for (; i >= 0; i--) {
1274 current = this[i]; 1291 current = this[i];
1275 if (!IS_UNDEFINED(current) || i in this) { 1292 if (!IS_UNDEFINED(current) || i in this) {
1276 i--; 1293 i--;
1277 break find_initial; 1294 break find_initial;
1278 } 1295 }
1279 } 1296 }
1280 throw MakeTypeError('reduce_no_initial', []); 1297 throw MakeTypeError('reduce_no_initial', []);
1281 } 1298 }
1282 1299
1300 var receiver = %GetDefaultReceiver(callback);
1283 for (; i >= 0; i--) { 1301 for (; i >= 0; i--) {
1284 var element = this[i]; 1302 var element = this[i];
1285 if (!IS_UNDEFINED(element) || i in this) { 1303 if (!IS_UNDEFINED(element) || i in this) {
1286 current = callback.call(void 0, current, element, i, this); 1304 current = %_CallFunction(receiver, current, element, i, this, callback);
1287 } 1305 }
1288 } 1306 }
1289 return current; 1307 return current;
1290 } 1308 }
1291 1309
1292 // ES5, 15.4.3.2 1310 // ES5, 15.4.3.2
1293 function ArrayIsArray(obj) { 1311 function ArrayIsArray(obj) {
1294 return IS_ARRAY(obj); 1312 return IS_ARRAY(obj);
1295 } 1313 }
1296 1314
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1359 InternalArray.prototype.join = getFunction("join", ArrayJoin); 1377 InternalArray.prototype.join = getFunction("join", ArrayJoin);
1360 InternalArray.prototype.pop = getFunction("pop", ArrayPop); 1378 InternalArray.prototype.pop = getFunction("pop", ArrayPop);
1361 InternalArray.prototype.push = getFunction("push", ArrayPush); 1379 InternalArray.prototype.push = getFunction("push", ArrayPush);
1362 InternalArray.prototype.toString = function() { 1380 InternalArray.prototype.toString = function() {
1363 return "Internal Array, length " + this.length; 1381 return "Internal Array, length " + this.length;
1364 }; 1382 };
1365 } 1383 }
1366 1384
1367 1385
1368 SetupArray(); 1386 SetupArray();
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698