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

Side by Side Diff: src/js/array.js

Issue 1560763002: Add Array support for @@species and subclassing (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Last couple comments Created 4 years, 11 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
« no previous file with comments | « src/builtins.cc ('k') | src/js/prologue.js » ('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 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
11 // ------------------------------------------------------------------- 11 // -------------------------------------------------------------------
12 // Imports 12 // Imports
13 13
14 var AddIndexedProperty; 14 var AddIndexedProperty;
15 var FLAG_harmony_tolength; 15 var FLAG_harmony_tolength;
16 var FLAG_harmony_species;
16 var GetIterator; 17 var GetIterator;
17 var GetMethod; 18 var GetMethod;
18 var GlobalArray = global.Array; 19 var GlobalArray = global.Array;
19 var InternalArray = utils.InternalArray; 20 var InternalArray = utils.InternalArray;
20 var InternalPackedArray = utils.InternalPackedArray; 21 var InternalPackedArray = utils.InternalPackedArray;
21 var MakeTypeError; 22 var MakeTypeError;
22 var MaxSimple; 23 var MaxSimple;
23 var MinSimple; 24 var MinSimple;
24 var ObjectDefineProperty; 25 var ObjectDefineProperty;
25 var ObjectHasOwnProperty; 26 var ObjectHasOwnProperty;
(...skipping 15 matching lines...) Expand all
41 ObjectDefineProperty = from.ObjectDefineProperty; 42 ObjectDefineProperty = from.ObjectDefineProperty;
42 ObjectHasOwnProperty = from.ObjectHasOwnProperty; 43 ObjectHasOwnProperty = from.ObjectHasOwnProperty;
43 ObserveBeginPerformSplice = from.ObserveBeginPerformSplice; 44 ObserveBeginPerformSplice = from.ObserveBeginPerformSplice;
44 ObserveEndPerformSplice = from.ObserveEndPerformSplice; 45 ObserveEndPerformSplice = from.ObserveEndPerformSplice;
45 ObserveEnqueueSpliceRecord = from.ObserveEnqueueSpliceRecord; 46 ObserveEnqueueSpliceRecord = from.ObserveEnqueueSpliceRecord;
46 SameValueZero = from.SameValueZero; 47 SameValueZero = from.SameValueZero;
47 }); 48 });
48 49
49 utils.ImportFromExperimental(function(from) { 50 utils.ImportFromExperimental(function(from) {
50 FLAG_harmony_tolength = from.FLAG_harmony_tolength; 51 FLAG_harmony_tolength = from.FLAG_harmony_tolength;
52 FLAG_harmony_species = from.FLAG_harmony_species;
51 }); 53 });
52 54
53 // ------------------------------------------------------------------- 55 // -------------------------------------------------------------------
54 56
57
58 function ArraySpeciesCreate(array, length) {
59 var constructor;
60 if (FLAG_harmony_species) {
61 constructor = %ArraySpeciesConstructor(array);
62 } else {
63 constructor = GlobalArray;
64 }
65 return new constructor(length);
66 }
67
68
69 function DefineIndexedProperty(array, i, value) {
70 if (FLAG_harmony_species) {
71 var result = ObjectDefineProperty(array, i, {
72 value: value, writable: true, configurable: true, enumerable: true
73 });
74 if (!result) throw MakeTypeError(kStrictCannotAssign, i);
75 } else {
76 AddIndexedProperty(array, i, value);
77 }
78 }
79
80
55 // Global list of arrays visited during toString, toLocaleString and 81 // Global list of arrays visited during toString, toLocaleString and
56 // join invocations. 82 // join invocations.
57 var visited_arrays = new InternalArray(); 83 var visited_arrays = new InternalArray();
58 84
59 85
60 // Gets a sorted array of array keys. Useful for operations on sparse 86 // Gets a sorted array of array keys. Useful for operations on sparse
61 // arrays. Dupes have not been removed. 87 // arrays. Dupes have not been removed.
62 function GetSortedArrayKeys(array, indices) { 88 function GetSortedArrayKeys(array, indices) {
63 var keys = new InternalArray(); 89 var keys = new InternalArray();
64 if (IS_NUMBER(indices)) { 90 if (IS_NUMBER(indices)) {
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 // This function implements the optimized splice implementation that can use 270 // This function implements the optimized splice implementation that can use
245 // special array operations to handle sparse arrays in a sensible fashion. 271 // special array operations to handle sparse arrays in a sensible fashion.
246 function SparseSlice(array, start_i, del_count, len, deleted_elements) { 272 function SparseSlice(array, start_i, del_count, len, deleted_elements) {
247 // Move deleted elements to a new array (the return value from splice). 273 // Move deleted elements to a new array (the return value from splice).
248 var indices = %GetArrayKeys(array, start_i + del_count); 274 var indices = %GetArrayKeys(array, start_i + del_count);
249 if (IS_NUMBER(indices)) { 275 if (IS_NUMBER(indices)) {
250 var limit = indices; 276 var limit = indices;
251 for (var i = start_i; i < limit; ++i) { 277 for (var i = start_i; i < limit; ++i) {
252 var current = array[i]; 278 var current = array[i];
253 if (!IS_UNDEFINED(current) || i in array) { 279 if (!IS_UNDEFINED(current) || i in array) {
254 AddIndexedProperty(deleted_elements, i - start_i, current); 280 DefineIndexedProperty(deleted_elements, i - start_i, current);
255 } 281 }
256 } 282 }
257 } else { 283 } else {
258 var length = indices.length; 284 var length = indices.length;
259 for (var k = 0; k < length; ++k) { 285 for (var k = 0; k < length; ++k) {
260 var key = indices[k]; 286 var key = indices[k];
261 if (!IS_UNDEFINED(key)) { 287 if (!IS_UNDEFINED(key)) {
262 if (key >= start_i) { 288 if (key >= start_i) {
263 var current = array[key]; 289 var current = array[key];
264 if (!IS_UNDEFINED(current) || key in array) { 290 if (!IS_UNDEFINED(current) || key in array) {
265 AddIndexedProperty(deleted_elements, key - start_i, current); 291 DefineIndexedProperty(deleted_elements, key - start_i, current);
266 } 292 }
267 } 293 }
268 } 294 }
269 } 295 }
270 } 296 }
271 } 297 }
272 298
273 299
274 // This function implements the optimized splice implementation that can use 300 // This function implements the optimized splice implementation that can use
275 // special array operations to handle sparse arrays in a sensible fashion. 301 // special array operations to handle sparse arrays in a sensible fashion.
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 361
336 // This is part of the old simple-minded splice. We are using it either 362 // This is part of the old simple-minded splice. We are using it either
337 // because the receiver is not an array (so we have no choice) or because we 363 // because the receiver is not an array (so we have no choice) or because we
338 // know we are not deleting or moving a lot of elements. 364 // know we are not deleting or moving a lot of elements.
339 function SimpleSlice(array, start_i, del_count, len, deleted_elements) { 365 function SimpleSlice(array, start_i, del_count, len, deleted_elements) {
340 var is_array = IS_ARRAY(array); 366 var is_array = IS_ARRAY(array);
341 for (var i = 0; i < del_count; i++) { 367 for (var i = 0; i < del_count; i++) {
342 var index = start_i + i; 368 var index = start_i + i;
343 if (HAS_INDEX(array, index, is_array)) { 369 if (HAS_INDEX(array, index, is_array)) {
344 var current = array[index]; 370 var current = array[index];
345 // The spec requires [[DefineOwnProperty]] here, AddIndexedProperty is 371 DefineIndexedProperty(deleted_elements, i, current);
346 // close enough (in that it ignores the prototype).
347 AddIndexedProperty(deleted_elements, i, current);
348 } 372 }
349 } 373 }
350 } 374 }
351 375
352 376
353 function SimpleMove(array, start_i, del_count, len, num_additional_args) { 377 function SimpleMove(array, start_i, del_count, len, num_additional_args) {
354 var is_array = IS_ARRAY(array); 378 var is_array = IS_ARRAY(array);
355 if (num_additional_args !== del_count) { 379 if (num_additional_args !== del_count) {
356 // Move the existing elements after the elements to be deleted 380 // Move the existing elements after the elements to be deleted
357 // to the right position in the resulting array. 381 // to the right position in the resulting array.
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
752 if (start_i > len) start_i = len; 776 if (start_i > len) start_i = len;
753 } 777 }
754 778
755 if (end_i < 0) { 779 if (end_i < 0) {
756 end_i += len; 780 end_i += len;
757 if (end_i < 0) end_i = 0; 781 if (end_i < 0) end_i = 0;
758 } else { 782 } else {
759 if (end_i > len) end_i = len; 783 if (end_i > len) end_i = len;
760 } 784 }
761 785
762 var result = []; 786 var result = ArraySpeciesCreate(array, MaxSimple(end_i - start_i, 0));
763 787
764 if (end_i < start_i) return result; 788 if (end_i < start_i) return result;
765 789
766 if (UseSparseVariant(array, len, IS_ARRAY(array), end_i - start_i)) { 790 if (UseSparseVariant(array, len, IS_ARRAY(array), end_i - start_i)) {
767 %NormalizeElements(array); 791 %NormalizeElements(array);
768 %NormalizeElements(result); 792 %NormalizeElements(result);
769 SparseSlice(array, start_i, end_i - start_i, len, result); 793 SparseSlice(array, start_i, end_i - start_i, len, result);
770 } else { 794 } else {
771 SimpleSlice(array, start_i, end_i - start_i, len, result); 795 SimpleSlice(array, start_i, end_i - start_i, len, result);
772 } 796 }
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
854 878
855 if (%IsObserved(this)) 879 if (%IsObserved(this))
856 return ObservedArraySplice.apply(this, arguments); 880 return ObservedArraySplice.apply(this, arguments);
857 881
858 var num_arguments = %_ArgumentsLength(); 882 var num_arguments = %_ArgumentsLength();
859 var array = TO_OBJECT(this); 883 var array = TO_OBJECT(this);
860 var len = TO_LENGTH_OR_UINT32(array.length); 884 var len = TO_LENGTH_OR_UINT32(array.length);
861 var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len); 885 var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len);
862 var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len, 886 var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len,
863 start_i); 887 start_i);
864 var deleted_elements = []; 888 var deleted_elements = ArraySpeciesCreate(array, del_count);
865 deleted_elements.length = del_count; 889 deleted_elements.length = del_count;
866 var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0; 890 var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0;
867 891
868 if (del_count != num_elements_to_add && %object_is_sealed(array)) { 892 if (del_count != num_elements_to_add && %object_is_sealed(array)) {
869 throw MakeTypeError(kArrayFunctionsOnSealed); 893 throw MakeTypeError(kArrayFunctionsOnSealed);
870 } else if (del_count > 0 && %object_is_frozen(array)) { 894 } else if (del_count > 0 && %object_is_frozen(array)) {
871 throw MakeTypeError(kArrayFunctionsOnFrozen); 895 throw MakeTypeError(kArrayFunctionsOnFrozen);
872 } 896 }
873 897
874 var changed_elements = del_count; 898 var changed_elements = del_count;
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
1194 1218
1195 var array = TO_OBJECT(this); 1219 var array = TO_OBJECT(this);
1196 var length = TO_LENGTH_OR_UINT32(array.length); 1220 var length = TO_LENGTH_OR_UINT32(array.length);
1197 return InnerArraySort(array, length, comparefn); 1221 return InnerArraySort(array, length, comparefn);
1198 } 1222 }
1199 1223
1200 1224
1201 // The following functions cannot be made efficient on sparse arrays while 1225 // The following functions cannot be made efficient on sparse arrays while
1202 // preserving the semantics, since the calls to the receiver function can add 1226 // preserving the semantics, since the calls to the receiver function can add
1203 // or delete elements from the array. 1227 // or delete elements from the array.
1204 function InnerArrayFilter(f, receiver, array, length) { 1228 function InnerArrayFilter(f, receiver, array, length, result) {
1205 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); 1229 var result_length = 0;
1206
1207 var accumulator = new InternalArray();
1208 var accumulator_length = 0;
1209 var is_array = IS_ARRAY(array); 1230 var is_array = IS_ARRAY(array);
1210 for (var i = 0; i < length; i++) { 1231 for (var i = 0; i < length; i++) {
1211 if (HAS_INDEX(array, i, is_array)) { 1232 if (HAS_INDEX(array, i, is_array)) {
1212 var element = array[i]; 1233 var element = array[i];
1213 if (%_Call(f, receiver, element, i, array)) { 1234 if (%_Call(f, receiver, element, i, array)) {
1214 accumulator[accumulator_length++] = element; 1235 DefineIndexedProperty(result, result_length, element);
1236 result_length++;
1215 } 1237 }
1216 } 1238 }
1217 } 1239 }
1218 var result = new GlobalArray();
1219 %MoveArrayContents(accumulator, result);
1220 return result; 1240 return result;
1221 } 1241 }
1222 1242
1223 1243
1244
1224 function ArrayFilter(f, receiver) { 1245 function ArrayFilter(f, receiver) {
1225 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.filter"); 1246 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.filter");
1226 1247
1227 // Pull out the length so that modifications to the length in the 1248 // Pull out the length so that modifications to the length in the
1228 // loop will not affect the looping and side effects are visible. 1249 // loop will not affect the looping and side effects are visible.
1229 var array = TO_OBJECT(this); 1250 var array = TO_OBJECT(this);
1230 var length = TO_LENGTH_OR_UINT32(array.length); 1251 var length = TO_LENGTH_OR_UINT32(array.length);
1231 return InnerArrayFilter(f, receiver, array, length); 1252 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
1253 var result = ArraySpeciesCreate(array, 0);
1254 return InnerArrayFilter(f, receiver, array, length, result);
1232 } 1255 }
1233 1256
1234 1257
1235 function InnerArrayForEach(f, receiver, array, length) { 1258 function InnerArrayForEach(f, receiver, array, length) {
1236 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); 1259 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
1237 1260
1238 var is_array = IS_ARRAY(array); 1261 var is_array = IS_ARRAY(array);
1239 for (var i = 0; i < length; i++) { 1262 for (var i = 0; i < length; i++) {
1240 if (HAS_INDEX(array, i, is_array)) { 1263 if (HAS_INDEX(array, i, is_array)) {
1241 var element = array[i]; 1264 var element = array[i];
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1300 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.every"); 1323 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.every");
1301 1324
1302 // Pull out the length so that modifications to the length in the 1325 // Pull out the length so that modifications to the length in the
1303 // loop will not affect the looping and side effects are visible. 1326 // loop will not affect the looping and side effects are visible.
1304 var array = TO_OBJECT(this); 1327 var array = TO_OBJECT(this);
1305 var length = TO_LENGTH_OR_UINT32(array.length); 1328 var length = TO_LENGTH_OR_UINT32(array.length);
1306 return InnerArrayEvery(f, receiver, array, length); 1329 return InnerArrayEvery(f, receiver, array, length);
1307 } 1330 }
1308 1331
1309 1332
1310 function InnerArrayMap(f, receiver, array, length) {
1311 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
1312
1313 var accumulator = new InternalArray(length);
1314 var is_array = IS_ARRAY(array);
1315 for (var i = 0; i < length; i++) {
1316 if (HAS_INDEX(array, i, is_array)) {
1317 var element = array[i];
1318 accumulator[i] = %_Call(f, receiver, element, i, array);
1319 }
1320 }
1321 var result = new GlobalArray();
1322 %MoveArrayContents(accumulator, result);
1323 return result;
1324 }
1325
1326
1327 function ArrayMap(f, receiver) { 1333 function ArrayMap(f, receiver) {
1328 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.map"); 1334 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.map");
1329 1335
1330 // Pull out the length so that modifications to the length in the 1336 // Pull out the length so that modifications to the length in the
1331 // loop will not affect the looping and side effects are visible. 1337 // loop will not affect the looping and side effects are visible.
1332 var array = TO_OBJECT(this); 1338 var array = TO_OBJECT(this);
1333 var length = TO_LENGTH_OR_UINT32(array.length); 1339 var length = TO_LENGTH_OR_UINT32(array.length);
1334 return InnerArrayMap(f, receiver, array, length); 1340 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
1341 var result = ArraySpeciesCreate(array, length);
1342 var is_array = IS_ARRAY(array);
1343 for (var i = 0; i < length; i++) {
1344 if (HAS_INDEX(array, i, is_array)) {
1345 var element = array[i];
1346 DefineIndexedProperty(result, i, %_Call(f, receiver, element, i, array));
1347 }
1348 }
1349 return result;
1335 } 1350 }
1336 1351
1337 1352
1338 // For .indexOf, we don't need to pass in the number of arguments 1353 // For .indexOf, we don't need to pass in the number of arguments
1339 // at the callsite since ToInteger(undefined) == 0; however, for 1354 // at the callsite since ToInteger(undefined) == 0; however, for
1340 // .lastIndexOf, we need to pass it, since the behavior for passing 1355 // .lastIndexOf, we need to pass it, since the behavior for passing
1341 // undefined is 0 but for not including the argument is length-1. 1356 // undefined is 0 but for not including the argument is length-1.
1342 function InnerArrayIndexOf(array, element, index, length) { 1357 function InnerArrayIndexOf(array, element, index, length) {
1343 if (length == 0) return -1; 1358 if (length == 0) return -1;
1344 if (IS_UNDEFINED(index)) { 1359 if (IS_UNDEFINED(index)) {
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after
1941 to.InnerArrayEvery = InnerArrayEvery; 1956 to.InnerArrayEvery = InnerArrayEvery;
1942 to.InnerArrayFill = InnerArrayFill; 1957 to.InnerArrayFill = InnerArrayFill;
1943 to.InnerArrayFilter = InnerArrayFilter; 1958 to.InnerArrayFilter = InnerArrayFilter;
1944 to.InnerArrayFind = InnerArrayFind; 1959 to.InnerArrayFind = InnerArrayFind;
1945 to.InnerArrayFindIndex = InnerArrayFindIndex; 1960 to.InnerArrayFindIndex = InnerArrayFindIndex;
1946 to.InnerArrayForEach = InnerArrayForEach; 1961 to.InnerArrayForEach = InnerArrayForEach;
1947 to.InnerArrayIncludes = InnerArrayIncludes; 1962 to.InnerArrayIncludes = InnerArrayIncludes;
1948 to.InnerArrayIndexOf = InnerArrayIndexOf; 1963 to.InnerArrayIndexOf = InnerArrayIndexOf;
1949 to.InnerArrayJoin = InnerArrayJoin; 1964 to.InnerArrayJoin = InnerArrayJoin;
1950 to.InnerArrayLastIndexOf = InnerArrayLastIndexOf; 1965 to.InnerArrayLastIndexOf = InnerArrayLastIndexOf;
1951 to.InnerArrayMap = InnerArrayMap;
1952 to.InnerArrayReduce = InnerArrayReduce; 1966 to.InnerArrayReduce = InnerArrayReduce;
1953 to.InnerArrayReduceRight = InnerArrayReduceRight; 1967 to.InnerArrayReduceRight = InnerArrayReduceRight;
1954 to.InnerArraySome = InnerArraySome; 1968 to.InnerArraySome = InnerArraySome;
1955 to.InnerArraySort = InnerArraySort; 1969 to.InnerArraySort = InnerArraySort;
1956 to.InnerArrayToLocaleString = InnerArrayToLocaleString; 1970 to.InnerArrayToLocaleString = InnerArrayToLocaleString;
1957 to.PackedArrayReverse = PackedArrayReverse; 1971 to.PackedArrayReverse = PackedArrayReverse;
1958 }); 1972 });
1959 1973
1960 %InstallToContext([ 1974 %InstallToContext([
1961 "array_pop", ArrayPop, 1975 "array_pop", ArrayPop,
1962 "array_push", ArrayPush, 1976 "array_push", ArrayPush,
1963 "array_shift", ArrayShift, 1977 "array_shift", ArrayShift,
1964 "array_splice", ArraySplice, 1978 "array_splice", ArraySplice,
1965 "array_slice", ArraySlice, 1979 "array_slice", ArraySlice,
1966 "array_unshift", ArrayUnshift, 1980 "array_unshift", ArrayUnshift,
1967 ]); 1981 ]);
1968 1982
1969 }); 1983 });
OLDNEW
« no previous file with comments | « src/builtins.cc ('k') | src/js/prologue.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698