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 |
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 n--; | 508 n--; |
509 var value = array[n]; | 509 var value = array[n]; |
510 %DeleteProperty_Strict(array, n); | 510 %DeleteProperty_Strict(array, n); |
511 array.length = n; | 511 array.length = n; |
512 return value; | 512 return value; |
513 } | 513 } |
514 | 514 |
515 | 515 |
516 function ObservedArrayPush() { | 516 function ObservedArrayPush() { |
517 var n = TO_LENGTH(this.length); | 517 var n = TO_LENGTH(this.length); |
518 var m = arguments.length; | 518 var m = %_ArgumentsLength(); |
519 | 519 |
520 try { | 520 try { |
521 ObserveBeginPerformSplice(this); | 521 ObserveBeginPerformSplice(this); |
522 for (var i = 0; i < m; i++) { | 522 for (var i = 0; i < m; i++) { |
523 this[i+n] = arguments[i]; | 523 this[i+n] = %_Arguments(i); |
524 } | 524 } |
525 var new_length = n + m; | 525 var new_length = n + m; |
526 this.length = new_length; | 526 this.length = new_length; |
527 } finally { | 527 } finally { |
528 ObserveEndPerformSplice(this); | 528 ObserveEndPerformSplice(this); |
529 ObserveEnqueueSpliceRecord(this, n, [], m); | 529 ObserveEnqueueSpliceRecord(this, n, [], m); |
530 } | 530 } |
531 | 531 |
532 return new_length; | 532 return new_length; |
533 } | 533 } |
534 | 534 |
535 | 535 |
536 // Appends the arguments to the end of the array and returns the new | 536 // Appends the arguments to the end of the array and returns the new |
537 // length of the array. See ECMA-262, section 15.4.4.7. | 537 // length of the array. See ECMA-262, section 15.4.4.7. |
538 function ArrayPush() { | 538 function ArrayPush() { |
539 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.push"); | 539 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.push"); |
540 | 540 |
541 if (%IsObserved(this)) | 541 if (%IsObserved(this)) |
542 return ObservedArrayPush.apply(this, arguments); | 542 return ObservedArrayPush.apply(this, arguments); |
543 | 543 |
544 var array = TO_OBJECT(this); | 544 var array = TO_OBJECT(this); |
545 var n = TO_LENGTH(array.length); | 545 var n = TO_LENGTH(array.length); |
546 var m = arguments.length; | 546 var m = %_ArgumentsLength(); |
547 | 547 |
548 // It appears that there is no enforced, absolute limit on the number of | 548 // It appears that there is no enforced, absolute limit on the number of |
549 // arguments, but it would surely blow the stack to use 2**30 or more. | 549 // arguments, but it would surely blow the stack to use 2**30 or more. |
550 // To avoid integer overflow, do the comparison to the max safe integer | 550 // To avoid integer overflow, do the comparison to the max safe integer |
551 // after subtracting 2**30 from both sides. (2**31 would seem like a | 551 // after subtracting 2**30 from both sides. (2**31 would seem like a |
552 // natural value, but it is negative in JS, and 2**32 is 1.) | 552 // natural value, but it is negative in JS, and 2**32 is 1.) |
553 if (m > (1 << 30) || (n - (1 << 30)) + m > kMaxSafeInteger - (1 << 30)) { | 553 if (m > (1 << 30) || (n - (1 << 30)) + m > kMaxSafeInteger - (1 << 30)) { |
554 throw MakeTypeError(kPushPastSafeLength, m, n); | 554 throw MakeTypeError(kPushPastSafeLength, m, n); |
555 } | 555 } |
556 | 556 |
557 for (var i = 0; i < m; i++) { | 557 for (var i = 0; i < m; i++) { |
558 array[i+n] = arguments[i]; | 558 array[i+n] = %_Arguments(i); |
559 } | 559 } |
560 | 560 |
561 var new_length = n + m; | 561 var new_length = n + m; |
562 array.length = new_length; | 562 array.length = new_length; |
563 return new_length; | 563 return new_length; |
564 } | 564 } |
565 | 565 |
566 | 566 |
567 // For implementing reverse() on large, sparse arrays. | 567 // For implementing reverse() on large, sparse arrays. |
568 function SparseReverse(array, len) { | 568 function SparseReverse(array, len) { |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
704 } | 704 } |
705 | 705 |
706 array.length = len - 1; | 706 array.length = len - 1; |
707 | 707 |
708 return first; | 708 return first; |
709 } | 709 } |
710 | 710 |
711 | 711 |
712 function ObservedArrayUnshift() { | 712 function ObservedArrayUnshift() { |
713 var len = TO_LENGTH(this.length); | 713 var len = TO_LENGTH(this.length); |
714 var num_arguments = arguments.length; | 714 var num_arguments = %_ArgumentsLength(); |
715 | 715 |
716 try { | 716 try { |
717 ObserveBeginPerformSplice(this); | 717 ObserveBeginPerformSplice(this); |
718 SimpleMove(this, 0, 0, len, num_arguments); | 718 SimpleMove(this, 0, 0, len, num_arguments); |
719 for (var i = 0; i < num_arguments; i++) { | 719 for (var i = 0; i < num_arguments; i++) { |
720 this[i] = arguments[i]; | 720 this[i] = %_Arguments(i); |
721 } | 721 } |
722 var new_length = len + num_arguments; | 722 var new_length = len + num_arguments; |
723 this.length = new_length; | 723 this.length = new_length; |
724 } finally { | 724 } finally { |
725 ObserveEndPerformSplice(this); | 725 ObserveEndPerformSplice(this); |
726 ObserveEnqueueSpliceRecord(this, 0, [], num_arguments); | 726 ObserveEnqueueSpliceRecord(this, 0, [], num_arguments); |
727 } | 727 } |
728 | 728 |
729 return new_length; | 729 return new_length; |
730 } | 730 } |
731 | 731 |
732 | 732 |
733 function ArrayUnshift(arg1) { // length == 1 | 733 function ArrayUnshift(arg1) { // length == 1 |
734 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.unshift"); | 734 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.unshift"); |
735 | 735 |
736 if (%IsObserved(this)) | 736 if (%IsObserved(this)) |
737 return ObservedArrayUnshift.apply(this, arguments); | 737 return ObservedArrayUnshift.apply(this, arguments); |
738 | 738 |
739 var array = TO_OBJECT(this); | 739 var array = TO_OBJECT(this); |
740 var len = TO_LENGTH(array.length); | 740 var len = TO_LENGTH(array.length); |
741 var num_arguments = arguments.length; | 741 var num_arguments = %_ArgumentsLength(); |
742 | 742 |
743 if (len > 0 && UseSparseVariant(array, len, IS_ARRAY(array), len) && | 743 if (len > 0 && UseSparseVariant(array, len, IS_ARRAY(array), len) && |
744 !%object_is_sealed(array)) { | 744 !%object_is_sealed(array)) { |
745 SparseMove(array, 0, 0, len, num_arguments); | 745 SparseMove(array, 0, 0, len, num_arguments); |
746 } else { | 746 } else { |
747 SimpleMove(array, 0, 0, len, num_arguments); | 747 SimpleMove(array, 0, 0, len, num_arguments); |
748 } | 748 } |
749 | 749 |
750 for (var i = 0; i < num_arguments; i++) { | 750 for (var i = 0; i < num_arguments; i++) { |
751 array[i] = arguments[i]; | 751 array[i] = %_Arguments(i); |
752 } | 752 } |
753 | 753 |
754 var new_length = len + num_arguments; | 754 var new_length = len + num_arguments; |
755 array.length = new_length; | 755 array.length = new_length; |
756 return new_length; | 756 return new_length; |
757 } | 757 } |
758 | 758 |
759 | 759 |
760 function ArraySlice(start, end) { | 760 function ArraySlice(start, end) { |
761 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.slice"); | 761 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.slice"); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
824 return 0; | 824 return 0; |
825 | 825 |
826 if (del_count > len - start_i) | 826 if (del_count > len - start_i) |
827 return len - start_i; | 827 return len - start_i; |
828 | 828 |
829 return del_count; | 829 return del_count; |
830 } | 830 } |
831 | 831 |
832 | 832 |
833 function ObservedArraySplice(start, delete_count) { | 833 function ObservedArraySplice(start, delete_count) { |
834 var num_arguments = arguments.length; | 834 var num_arguments = %_ArgumentsLength(); |
835 var len = TO_LENGTH(this.length); | 835 var len = TO_LENGTH(this.length); |
836 var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len); | 836 var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len); |
837 var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len, | 837 var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len, |
838 start_i); | 838 start_i); |
839 var deleted_elements = []; | 839 var deleted_elements = []; |
840 deleted_elements.length = del_count; | 840 deleted_elements.length = del_count; |
841 var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0; | 841 var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0; |
842 | 842 |
843 try { | 843 try { |
844 ObserveBeginPerformSplice(this); | 844 ObserveBeginPerformSplice(this); |
845 | 845 |
846 SimpleSlice(this, start_i, del_count, len, deleted_elements); | 846 SimpleSlice(this, start_i, del_count, len, deleted_elements); |
847 SimpleMove(this, start_i, del_count, len, num_elements_to_add); | 847 SimpleMove(this, start_i, del_count, len, num_elements_to_add); |
848 | 848 |
849 // Insert the arguments into the resulting array in | 849 // Insert the arguments into the resulting array in |
850 // place of the deleted elements. | 850 // place of the deleted elements. |
851 var i = start_i; | 851 var i = start_i; |
852 var arguments_index = 2; | 852 var arguments_index = 2; |
853 var arguments_length = arguments.length; | 853 var arguments_length = %_ArgumentsLength(); |
854 while (arguments_index < arguments_length) { | 854 while (arguments_index < arguments_length) { |
855 this[i++] = arguments[arguments_index++]; | 855 this[i++] = %_Arguments(arguments_index++); |
856 } | 856 } |
857 this.length = len - del_count + num_elements_to_add; | 857 this.length = len - del_count + num_elements_to_add; |
858 | 858 |
859 } finally { | 859 } finally { |
860 ObserveEndPerformSplice(this); | 860 ObserveEndPerformSplice(this); |
861 if (deleted_elements.length || num_elements_to_add) { | 861 if (deleted_elements.length || num_elements_to_add) { |
862 ObserveEnqueueSpliceRecord(this, | 862 ObserveEnqueueSpliceRecord(this, |
863 start_i, | 863 start_i, |
864 deleted_elements.slice(), | 864 deleted_elements.slice(), |
865 num_elements_to_add); | 865 num_elements_to_add); |
866 } | 866 } |
867 } | 867 } |
868 | 868 |
869 // Return the deleted elements. | 869 // Return the deleted elements. |
870 return deleted_elements; | 870 return deleted_elements; |
871 } | 871 } |
872 | 872 |
873 | 873 |
874 function ArraySplice(start, delete_count) { | 874 function ArraySplice(start, delete_count) { |
875 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.splice"); | 875 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.splice"); |
876 | 876 |
877 if (%IsObserved(this)) | 877 if (%IsObserved(this)) |
878 return ObservedArraySplice.apply(this, arguments); | 878 return ObservedArraySplice.apply(this, arguments); |
879 | 879 |
880 var num_arguments = arguments.length; | 880 var num_arguments = %_ArgumentsLength(); |
881 var array = TO_OBJECT(this); | 881 var array = TO_OBJECT(this); |
882 var len = TO_LENGTH(array.length); | 882 var len = TO_LENGTH(array.length); |
883 var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len); | 883 var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len); |
884 var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len, | 884 var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len, |
885 start_i); | 885 start_i); |
886 var deleted_elements = ArraySpeciesCreate(array, del_count); | 886 var deleted_elements = ArraySpeciesCreate(array, del_count); |
887 deleted_elements.length = del_count; | 887 deleted_elements.length = del_count; |
888 var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0; | 888 var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0; |
889 | 889 |
890 if (del_count != num_elements_to_add && %object_is_sealed(array)) { | 890 if (del_count != num_elements_to_add && %object_is_sealed(array)) { |
(...skipping 15 matching lines...) Expand all Loading... |
906 SparseMove(array, start_i, del_count, len, num_elements_to_add); | 906 SparseMove(array, start_i, del_count, len, num_elements_to_add); |
907 } else { | 907 } else { |
908 SimpleSlice(array, start_i, del_count, len, deleted_elements); | 908 SimpleSlice(array, start_i, del_count, len, deleted_elements); |
909 SimpleMove(array, start_i, del_count, len, num_elements_to_add); | 909 SimpleMove(array, start_i, del_count, len, num_elements_to_add); |
910 } | 910 } |
911 | 911 |
912 // Insert the arguments into the resulting array in | 912 // Insert the arguments into the resulting array in |
913 // place of the deleted elements. | 913 // place of the deleted elements. |
914 var i = start_i; | 914 var i = start_i; |
915 var arguments_index = 2; | 915 var arguments_index = 2; |
916 var arguments_length = arguments.length; | 916 var arguments_length = %_ArgumentsLength(); |
917 while (arguments_index < arguments_length) { | 917 while (arguments_index < arguments_length) { |
918 array[i++] = arguments[arguments_index++]; | 918 array[i++] = %_Arguments(arguments_index++); |
919 } | 919 } |
920 array.length = len - del_count + num_elements_to_add; | 920 array.length = len - del_count + num_elements_to_add; |
921 | 921 |
922 // Return the deleted elements. | 922 // Return the deleted elements. |
923 return deleted_elements; | 923 return deleted_elements; |
924 } | 924 } |
925 | 925 |
926 | 926 |
927 function InnerArraySort(array, length, comparefn) { | 927 function InnerArraySort(array, length, comparefn) { |
928 // In-place QuickSort algorithm. | 928 // In-place QuickSort algorithm. |
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1462 } | 1462 } |
1463 return -1; | 1463 return -1; |
1464 } | 1464 } |
1465 | 1465 |
1466 | 1466 |
1467 function ArrayLastIndexOf(element, index) { | 1467 function ArrayLastIndexOf(element, index) { |
1468 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.lastIndexOf"); | 1468 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.lastIndexOf"); |
1469 | 1469 |
1470 var length = TO_LENGTH(this.length); | 1470 var length = TO_LENGTH(this.length); |
1471 return InnerArrayLastIndexOf(this, element, index, length, | 1471 return InnerArrayLastIndexOf(this, element, index, length, |
1472 arguments.length); | 1472 %_ArgumentsLength()); |
1473 } | 1473 } |
1474 | 1474 |
1475 | 1475 |
1476 function InnerArrayReduce(callback, current, array, length, argumentsLength) { | 1476 function InnerArrayReduce(callback, current, array, length, argumentsLength) { |
1477 if (!IS_CALLABLE(callback)) { | 1477 if (!IS_CALLABLE(callback)) { |
1478 throw MakeTypeError(kCalledNonCallable, callback); | 1478 throw MakeTypeError(kCalledNonCallable, callback); |
1479 } | 1479 } |
1480 | 1480 |
1481 var is_array = IS_ARRAY(array); | 1481 var is_array = IS_ARRAY(array); |
1482 var i = 0; | 1482 var i = 0; |
(...skipping 18 matching lines...) Expand all Loading... |
1501 | 1501 |
1502 | 1502 |
1503 function ArrayReduce(callback, current) { | 1503 function ArrayReduce(callback, current) { |
1504 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduce"); | 1504 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduce"); |
1505 | 1505 |
1506 // Pull out the length so that modifications to the length in the | 1506 // Pull out the length so that modifications to the length in the |
1507 // loop will not affect the looping and side effects are visible. | 1507 // loop will not affect the looping and side effects are visible. |
1508 var array = TO_OBJECT(this); | 1508 var array = TO_OBJECT(this); |
1509 var length = TO_LENGTH(array.length); | 1509 var length = TO_LENGTH(array.length); |
1510 return InnerArrayReduce(callback, current, array, length, | 1510 return InnerArrayReduce(callback, current, array, length, |
1511 arguments.length); | 1511 %_ArgumentsLength()); |
1512 } | 1512 } |
1513 | 1513 |
1514 | 1514 |
1515 function InnerArrayReduceRight(callback, current, array, length, | 1515 function InnerArrayReduceRight(callback, current, array, length, |
1516 argumentsLength) { | 1516 argumentsLength) { |
1517 if (!IS_CALLABLE(callback)) { | 1517 if (!IS_CALLABLE(callback)) { |
1518 throw MakeTypeError(kCalledNonCallable, callback); | 1518 throw MakeTypeError(kCalledNonCallable, callback); |
1519 } | 1519 } |
1520 | 1520 |
1521 var is_array = IS_ARRAY(array); | 1521 var is_array = IS_ARRAY(array); |
(...skipping 19 matching lines...) Expand all Loading... |
1541 | 1541 |
1542 | 1542 |
1543 function ArrayReduceRight(callback, current) { | 1543 function ArrayReduceRight(callback, current) { |
1544 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduceRight"); | 1544 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduceRight"); |
1545 | 1545 |
1546 // Pull out the length so that side effects are visible before the | 1546 // Pull out the length so that side effects are visible before the |
1547 // callback function is checked. | 1547 // callback function is checked. |
1548 var array = TO_OBJECT(this); | 1548 var array = TO_OBJECT(this); |
1549 var length = TO_LENGTH(array.length); | 1549 var length = TO_LENGTH(array.length); |
1550 return InnerArrayReduceRight(callback, current, array, length, | 1550 return InnerArrayReduceRight(callback, current, array, length, |
1551 arguments.length); | 1551 %_ArgumentsLength()); |
1552 } | 1552 } |
1553 | 1553 |
1554 | 1554 |
1555 function InnerArrayCopyWithin(target, start, end, array, length) { | 1555 function InnerArrayCopyWithin(target, start, end, array, length) { |
1556 target = TO_INTEGER(target); | 1556 target = TO_INTEGER(target); |
1557 var to; | 1557 var to; |
1558 if (target < 0) { | 1558 if (target < 0) { |
1559 to = MaxSimple(length + target, 0); | 1559 to = MaxSimple(length + target, 0); |
1560 } else { | 1560 } else { |
1561 to = MinSimple(target, length); | 1561 to = MinSimple(target, length); |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1815 AddArrayElement(this, result, k, mappedValue); | 1815 AddArrayElement(this, result, k, mappedValue); |
1816 } | 1816 } |
1817 | 1817 |
1818 result.length = k; | 1818 result.length = k; |
1819 return result; | 1819 return result; |
1820 } | 1820 } |
1821 } | 1821 } |
1822 | 1822 |
1823 | 1823 |
1824 // ES6, draft 05-22-14, section 22.1.2.3 | 1824 // ES6, draft 05-22-14, section 22.1.2.3 |
1825 function ArrayOf(...args) { | 1825 function ArrayOf() { |
1826 var length = args.length; | 1826 var length = %_ArgumentsLength(); |
1827 var constructor = this; | 1827 var constructor = this; |
1828 // TODO: Implement IsConstructor (ES6 section 7.2.5) | 1828 // TODO: Implement IsConstructor (ES6 section 7.2.5) |
1829 var array = %IsConstructor(constructor) ? new constructor(length) : []; | 1829 var array = %IsConstructor(constructor) ? new constructor(length) : []; |
1830 for (var i = 0; i < length; i++) { | 1830 for (var i = 0; i < length; i++) { |
1831 AddArrayElement(constructor, array, i, args[i]); | 1831 AddArrayElement(constructor, array, i, %_Arguments(i)); |
1832 } | 1832 } |
1833 array.length = length; | 1833 array.length = length; |
1834 return array; | 1834 return array; |
1835 } | 1835 } |
1836 | 1836 |
1837 // ------------------------------------------------------------------- | 1837 // ------------------------------------------------------------------- |
1838 | 1838 |
1839 // Set up non-enumerable constructor property on the Array.prototype | 1839 // Set up non-enumerable constructor property on the Array.prototype |
1840 // object. | 1840 // object. |
1841 %AddNamedProperty(GlobalArray.prototype, "constructor", GlobalArray, | 1841 %AddNamedProperty(GlobalArray.prototype, "constructor", GlobalArray, |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1972 %InstallToContext([ | 1972 %InstallToContext([ |
1973 "array_pop", ArrayPop, | 1973 "array_pop", ArrayPop, |
1974 "array_push", ArrayPush, | 1974 "array_push", ArrayPush, |
1975 "array_shift", ArrayShift, | 1975 "array_shift", ArrayShift, |
1976 "array_splice", ArraySplice, | 1976 "array_splice", ArraySplice, |
1977 "array_slice", ArraySlice, | 1977 "array_slice", ArraySlice, |
1978 "array_unshift", ArrayUnshift, | 1978 "array_unshift", ArrayUnshift, |
1979 ]); | 1979 ]); |
1980 | 1980 |
1981 }); | 1981 }); |
OLD | NEW |