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 |
11 // ------------------------------------------------------------------- | 11 // ------------------------------------------------------------------- |
12 // Imports | 12 // Imports |
13 | 13 |
14 var AddIndexedProperty; | |
15 var FLAG_harmony_species; | 14 var FLAG_harmony_species; |
16 var GetIterator; | 15 var GetIterator; |
17 var GetMethod; | 16 var GetMethod; |
18 var GlobalArray = global.Array; | 17 var GlobalArray = global.Array; |
19 var InternalArray = utils.InternalArray; | 18 var InternalArray = utils.InternalArray; |
20 var InternalPackedArray = utils.InternalPackedArray; | 19 var InternalPackedArray = utils.InternalPackedArray; |
21 var MakeTypeError; | 20 var MakeTypeError; |
22 var MaxSimple; | 21 var MaxSimple; |
23 var MinSimple; | 22 var MinSimple; |
24 var ObjectDefineProperty; | 23 var ObjectDefineProperty; |
25 var ObjectHasOwnProperty; | 24 var ObjectHasOwnProperty; |
26 var ObjectToString = utils.ImportNow("object_to_string"); | 25 var ObjectToString = utils.ImportNow("object_to_string"); |
27 var ObserveBeginPerformSplice; | 26 var ObserveBeginPerformSplice; |
28 var ObserveEndPerformSplice; | 27 var ObserveEndPerformSplice; |
29 var ObserveEnqueueSpliceRecord; | 28 var ObserveEnqueueSpliceRecord; |
30 var iteratorSymbol = utils.ImportNow("iterator_symbol"); | 29 var iteratorSymbol = utils.ImportNow("iterator_symbol"); |
31 var unscopablesSymbol = utils.ImportNow("unscopables_symbol"); | 30 var unscopablesSymbol = utils.ImportNow("unscopables_symbol"); |
32 | 31 |
33 utils.Import(function(from) { | 32 utils.Import(function(from) { |
34 AddIndexedProperty = from.AddIndexedProperty; | |
35 GetIterator = from.GetIterator; | 33 GetIterator = from.GetIterator; |
36 GetMethod = from.GetMethod; | 34 GetMethod = from.GetMethod; |
37 MakeTypeError = from.MakeTypeError; | 35 MakeTypeError = from.MakeTypeError; |
38 MaxSimple = from.MaxSimple; | 36 MaxSimple = from.MaxSimple; |
39 MinSimple = from.MinSimple; | 37 MinSimple = from.MinSimple; |
40 ObjectDefineProperty = from.ObjectDefineProperty; | 38 ObjectDefineProperty = from.ObjectDefineProperty; |
41 ObjectHasOwnProperty = from.ObjectHasOwnProperty; | 39 ObjectHasOwnProperty = from.ObjectHasOwnProperty; |
42 ObserveBeginPerformSplice = from.ObserveBeginPerformSplice; | 40 ObserveBeginPerformSplice = from.ObserveBeginPerformSplice; |
43 ObserveEndPerformSplice = from.ObserveEndPerformSplice; | 41 ObserveEndPerformSplice = from.ObserveEndPerformSplice; |
44 ObserveEnqueueSpliceRecord = from.ObserveEnqueueSpliceRecord; | 42 ObserveEnqueueSpliceRecord = from.ObserveEnqueueSpliceRecord; |
(...skipping 10 matching lines...) Expand all Loading... |
55 var constructor; | 53 var constructor; |
56 if (FLAG_harmony_species) { | 54 if (FLAG_harmony_species) { |
57 constructor = %ArraySpeciesConstructor(array); | 55 constructor = %ArraySpeciesConstructor(array); |
58 } else { | 56 } else { |
59 constructor = GlobalArray; | 57 constructor = GlobalArray; |
60 } | 58 } |
61 return new constructor(length); | 59 return new constructor(length); |
62 } | 60 } |
63 | 61 |
64 | 62 |
65 function DefineIndexedProperty(array, i, value) { | |
66 if (FLAG_harmony_species) { | |
67 var result = ObjectDefineProperty(array, i, { | |
68 value: value, writable: true, configurable: true, enumerable: true | |
69 }); | |
70 if (!result) throw MakeTypeError(kStrictCannotAssign, i); | |
71 } else { | |
72 AddIndexedProperty(array, i, value); | |
73 } | |
74 } | |
75 | |
76 function KeySortCompare(a, b) { | 63 function KeySortCompare(a, b) { |
77 return a - b; | 64 return a - b; |
78 } | 65 } |
79 | 66 |
80 function GetSortedArrayKeys(array, indices) { | 67 function GetSortedArrayKeys(array, indices) { |
81 if (IS_NUMBER(indices)) { | 68 if (IS_NUMBER(indices)) { |
82 var keys = new InternalArray(); | 69 var keys = new InternalArray(); |
83 // It's an interval | 70 // It's an interval |
84 var limit = indices; | 71 var limit = indices; |
85 for (var i = 0; i < limit; ++i) { | 72 for (var i = 0; i < limit; ++i) { |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 // This function implements the optimized splice implementation that can use | 245 // This function implements the optimized splice implementation that can use |
259 // special array operations to handle sparse arrays in a sensible fashion. | 246 // special array operations to handle sparse arrays in a sensible fashion. |
260 function SparseSlice(array, start_i, del_count, len, deleted_elements) { | 247 function SparseSlice(array, start_i, del_count, len, deleted_elements) { |
261 // Move deleted elements to a new array (the return value from splice). | 248 // Move deleted elements to a new array (the return value from splice). |
262 var indices = %GetArrayKeys(array, start_i + del_count); | 249 var indices = %GetArrayKeys(array, start_i + del_count); |
263 if (IS_NUMBER(indices)) { | 250 if (IS_NUMBER(indices)) { |
264 var limit = indices; | 251 var limit = indices; |
265 for (var i = start_i; i < limit; ++i) { | 252 for (var i = start_i; i < limit; ++i) { |
266 var current = array[i]; | 253 var current = array[i]; |
267 if (!IS_UNDEFINED(current) || i in array) { | 254 if (!IS_UNDEFINED(current) || i in array) { |
268 DefineIndexedProperty(deleted_elements, i - start_i, current); | 255 %CreateDataProperty(deleted_elements, i - start_i, current); |
269 } | 256 } |
270 } | 257 } |
271 } else { | 258 } else { |
272 var length = indices.length; | 259 var length = indices.length; |
273 for (var k = 0; k < length; ++k) { | 260 for (var k = 0; k < length; ++k) { |
274 var key = indices[k]; | 261 var key = indices[k]; |
275 if (key >= start_i) { | 262 if (key >= start_i) { |
276 var current = array[key]; | 263 var current = array[key]; |
277 if (!IS_UNDEFINED(current) || key in array) { | 264 if (!IS_UNDEFINED(current) || key in array) { |
278 DefineIndexedProperty(deleted_elements, key - start_i, current); | 265 %CreateDataProperty(deleted_elements, key - start_i, current); |
279 } | 266 } |
280 } | 267 } |
281 } | 268 } |
282 } | 269 } |
283 } | 270 } |
284 | 271 |
285 | 272 |
286 // This function implements the optimized splice implementation that can use | 273 // This function implements the optimized splice implementation that can use |
287 // special array operations to handle sparse arrays in a sensible fashion. | 274 // special array operations to handle sparse arrays in a sensible fashion. |
288 function SparseMove(array, start_i, del_count, len, num_additional_args) { | 275 function SparseMove(array, start_i, del_count, len, num_additional_args) { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 | 332 |
346 // This is part of the old simple-minded splice. We are using it either | 333 // This is part of the old simple-minded splice. We are using it either |
347 // because the receiver is not an array (so we have no choice) or because we | 334 // because the receiver is not an array (so we have no choice) or because we |
348 // know we are not deleting or moving a lot of elements. | 335 // know we are not deleting or moving a lot of elements. |
349 function SimpleSlice(array, start_i, del_count, len, deleted_elements) { | 336 function SimpleSlice(array, start_i, del_count, len, deleted_elements) { |
350 var is_array = IS_ARRAY(array); | 337 var is_array = IS_ARRAY(array); |
351 for (var i = 0; i < del_count; i++) { | 338 for (var i = 0; i < del_count; i++) { |
352 var index = start_i + i; | 339 var index = start_i + i; |
353 if (HAS_INDEX(array, index, is_array)) { | 340 if (HAS_INDEX(array, index, is_array)) { |
354 var current = array[index]; | 341 var current = array[index]; |
355 DefineIndexedProperty(deleted_elements, i, current); | 342 %CreateDataProperty(deleted_elements, i, current); |
356 } | 343 } |
357 } | 344 } |
358 } | 345 } |
359 | 346 |
360 | 347 |
361 function SimpleMove(array, start_i, del_count, len, num_additional_args) { | 348 function SimpleMove(array, start_i, del_count, len, num_additional_args) { |
362 var is_array = IS_ARRAY(array); | 349 var is_array = IS_ARRAY(array); |
363 if (num_additional_args !== del_count) { | 350 if (num_additional_args !== del_count) { |
364 // Move the existing elements after the elements to be deleted | 351 // Move the existing elements after the elements to be deleted |
365 // to the right position in the resulting array. | 352 // to the right position in the resulting array. |
(...skipping 838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1204 // The following functions cannot be made efficient on sparse arrays while | 1191 // The following functions cannot be made efficient on sparse arrays while |
1205 // preserving the semantics, since the calls to the receiver function can add | 1192 // preserving the semantics, since the calls to the receiver function can add |
1206 // or delete elements from the array. | 1193 // or delete elements from the array. |
1207 function InnerArrayFilter(f, receiver, array, length, result) { | 1194 function InnerArrayFilter(f, receiver, array, length, result) { |
1208 var result_length = 0; | 1195 var result_length = 0; |
1209 var is_array = IS_ARRAY(array); | 1196 var is_array = IS_ARRAY(array); |
1210 for (var i = 0; i < length; i++) { | 1197 for (var i = 0; i < length; i++) { |
1211 if (HAS_INDEX(array, i, is_array)) { | 1198 if (HAS_INDEX(array, i, is_array)) { |
1212 var element = array[i]; | 1199 var element = array[i]; |
1213 if (%_Call(f, receiver, element, i, array)) { | 1200 if (%_Call(f, receiver, element, i, array)) { |
1214 DefineIndexedProperty(result, result_length, element); | 1201 %CreateDataProperty(result, result_length, element); |
1215 result_length++; | 1202 result_length++; |
1216 } | 1203 } |
1217 } | 1204 } |
1218 } | 1205 } |
1219 return result; | 1206 return result; |
1220 } | 1207 } |
1221 | 1208 |
1222 | 1209 |
1223 | 1210 |
1224 function ArrayFilter(f, receiver) { | 1211 function ArrayFilter(f, receiver) { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1324 // Pull out the length so that modifications to the length in the | 1311 // Pull out the length so that modifications to the length in the |
1325 // loop will not affect the looping and side effects are visible. | 1312 // loop will not affect the looping and side effects are visible. |
1326 var array = TO_OBJECT(this); | 1313 var array = TO_OBJECT(this); |
1327 var length = TO_LENGTH(array.length); | 1314 var length = TO_LENGTH(array.length); |
1328 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); | 1315 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); |
1329 var result = ArraySpeciesCreate(array, length); | 1316 var result = ArraySpeciesCreate(array, length); |
1330 var is_array = IS_ARRAY(array); | 1317 var is_array = IS_ARRAY(array); |
1331 for (var i = 0; i < length; i++) { | 1318 for (var i = 0; i < length; i++) { |
1332 if (HAS_INDEX(array, i, is_array)) { | 1319 if (HAS_INDEX(array, i, is_array)) { |
1333 var element = array[i]; | 1320 var element = array[i]; |
1334 DefineIndexedProperty(result, i, %_Call(f, receiver, element, i, array)); | 1321 %CreateDataProperty(result, i, %_Call(f, receiver, element, i, array)); |
1335 } | 1322 } |
1336 } | 1323 } |
1337 return result; | 1324 return result; |
1338 } | 1325 } |
1339 | 1326 |
1340 | 1327 |
1341 // For .indexOf, we don't need to pass in the number of arguments | 1328 // For .indexOf, we don't need to pass in the number of arguments |
1342 // at the callsite since ToInteger(undefined) == 0; however, for | 1329 // at the callsite since ToInteger(undefined) == 0; however, for |
1343 // .lastIndexOf, we need to pass it, since the behavior for passing | 1330 // .lastIndexOf, we need to pass it, since the behavior for passing |
1344 // undefined is 0 but for not including the argument is length-1. | 1331 // undefined is 0 but for not including the argument is length-1. |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1729 function ArrayIncludes(searchElement, fromIndex) { | 1716 function ArrayIncludes(searchElement, fromIndex) { |
1730 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.includes"); | 1717 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.includes"); |
1731 | 1718 |
1732 var array = TO_OBJECT(this); | 1719 var array = TO_OBJECT(this); |
1733 var length = TO_LENGTH(array.length); | 1720 var length = TO_LENGTH(array.length); |
1734 | 1721 |
1735 return InnerArrayIncludes(searchElement, fromIndex, array, length); | 1722 return InnerArrayIncludes(searchElement, fromIndex, array, length); |
1736 } | 1723 } |
1737 | 1724 |
1738 | 1725 |
1739 function AddArrayElement(constructor, array, i, value) { | |
1740 if (constructor === GlobalArray) { | |
1741 AddIndexedProperty(array, i, value); | |
1742 } else { | |
1743 ObjectDefineProperty(array, i, { | |
1744 value: value, writable: true, configurable: true, enumerable: true | |
1745 }); | |
1746 } | |
1747 } | |
1748 | |
1749 | |
1750 // ES6, draft 10-14-14, section 22.1.2.1 | 1726 // ES6, draft 10-14-14, section 22.1.2.1 |
1751 function ArrayFrom(arrayLike, mapfn, receiver) { | 1727 function ArrayFrom(arrayLike, mapfn, receiver) { |
1752 var items = TO_OBJECT(arrayLike); | 1728 var items = TO_OBJECT(arrayLike); |
1753 var mapping = !IS_UNDEFINED(mapfn); | 1729 var mapping = !IS_UNDEFINED(mapfn); |
1754 | 1730 |
1755 if (mapping) { | 1731 if (mapping) { |
1756 if (!IS_CALLABLE(mapfn)) { | 1732 if (!IS_CALLABLE(mapfn)) { |
1757 throw MakeTypeError(kCalledNonCallable, mapfn); | 1733 throw MakeTypeError(kCalledNonCallable, mapfn); |
1758 } | 1734 } |
1759 } | 1735 } |
1760 | 1736 |
1761 var iterable = GetMethod(items, iteratorSymbol); | 1737 var iterable = GetMethod(items, iteratorSymbol); |
1762 var k; | 1738 var k; |
1763 var result; | 1739 var result; |
1764 var mappedValue; | 1740 var mappedValue; |
1765 var nextValue; | 1741 var nextValue; |
1766 | 1742 |
1767 if (!IS_UNDEFINED(iterable)) { | 1743 if (!IS_UNDEFINED(iterable)) { |
1768 result = %IsConstructor(this) ? new this() : []; | 1744 result = %IsConstructor(this) ? new this() : []; |
1769 k = 0; | 1745 k = 0; |
1770 | 1746 |
1771 for (nextValue of | 1747 for (nextValue of |
1772 { [iteratorSymbol]() { return GetIterator(items, iterable) } }) { | 1748 { [iteratorSymbol]() { return GetIterator(items, iterable) } }) { |
1773 if (mapping) { | 1749 if (mapping) { |
1774 mappedValue = %_Call(mapfn, receiver, nextValue, k); | 1750 mappedValue = %_Call(mapfn, receiver, nextValue, k); |
1775 } else { | 1751 } else { |
1776 mappedValue = nextValue; | 1752 mappedValue = nextValue; |
1777 } | 1753 } |
1778 AddArrayElement(this, result, k, mappedValue); | 1754 %CreateDataProperty(result, k, mappedValue); |
1779 k++; | 1755 k++; |
1780 } | 1756 } |
1781 result.length = k; | 1757 result.length = k; |
1782 return result; | 1758 return result; |
1783 } else { | 1759 } else { |
1784 var len = TO_LENGTH(items.length); | 1760 var len = TO_LENGTH(items.length); |
1785 result = %IsConstructor(this) ? new this(len) : new GlobalArray(len); | 1761 result = %IsConstructor(this) ? new this(len) : new GlobalArray(len); |
1786 | 1762 |
1787 for (k = 0; k < len; ++k) { | 1763 for (k = 0; k < len; ++k) { |
1788 nextValue = items[k]; | 1764 nextValue = items[k]; |
1789 if (mapping) { | 1765 if (mapping) { |
1790 mappedValue = %_Call(mapfn, receiver, nextValue, k); | 1766 mappedValue = %_Call(mapfn, receiver, nextValue, k); |
1791 } else { | 1767 } else { |
1792 mappedValue = nextValue; | 1768 mappedValue = nextValue; |
1793 } | 1769 } |
1794 AddArrayElement(this, result, k, mappedValue); | 1770 %CreateDataProperty(result, k, mappedValue); |
1795 } | 1771 } |
1796 | 1772 |
1797 result.length = k; | 1773 result.length = k; |
1798 return result; | 1774 return result; |
1799 } | 1775 } |
1800 } | 1776 } |
1801 | 1777 |
1802 | 1778 |
1803 // ES6, draft 05-22-14, section 22.1.2.3 | 1779 // ES6, draft 05-22-14, section 22.1.2.3 |
1804 function ArrayOf(...args) { | 1780 function ArrayOf(...args) { |
1805 var length = args.length; | 1781 var length = args.length; |
1806 var constructor = this; | 1782 var constructor = this; |
1807 // TODO: Implement IsConstructor (ES6 section 7.2.5) | 1783 // TODO: Implement IsConstructor (ES6 section 7.2.5) |
1808 var array = %IsConstructor(constructor) ? new constructor(length) : []; | 1784 var array = %IsConstructor(constructor) ? new constructor(length) : []; |
1809 for (var i = 0; i < length; i++) { | 1785 for (var i = 0; i < length; i++) { |
1810 AddArrayElement(constructor, array, i, args[i]); | 1786 %CreateDataProperty(array, i, args[i]); |
1811 } | 1787 } |
1812 array.length = length; | 1788 array.length = length; |
1813 return array; | 1789 return array; |
1814 } | 1790 } |
1815 | 1791 |
1816 // ------------------------------------------------------------------- | 1792 // ------------------------------------------------------------------- |
1817 | 1793 |
1818 // Set up non-enumerable constructor property on the Array.prototype | 1794 // Set up non-enumerable constructor property on the Array.prototype |
1819 // object. | 1795 // object. |
1820 %AddNamedProperty(GlobalArray.prototype, "constructor", GlobalArray, | 1796 %AddNamedProperty(GlobalArray.prototype, "constructor", GlobalArray, |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1955 %InstallToContext([ | 1931 %InstallToContext([ |
1956 "array_pop", ArrayPop, | 1932 "array_pop", ArrayPop, |
1957 "array_push", ArrayPush, | 1933 "array_push", ArrayPush, |
1958 "array_shift", ArrayShift, | 1934 "array_shift", ArrayShift, |
1959 "array_splice", ArraySplice, | 1935 "array_splice", ArraySplice, |
1960 "array_slice", ArraySlice, | 1936 "array_slice", ArraySlice, |
1961 "array_unshift", ArrayUnshift, | 1937 "array_unshift", ArrayUnshift, |
1962 ]); | 1938 ]); |
1963 | 1939 |
1964 }); | 1940 }); |
OLD | NEW |