OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 var arrayLen = array.length; | 373 var arrayLen = array.length; |
374 var len = TO_UINT32(arrayLen); | 374 var len = TO_UINT32(arrayLen); |
375 if (len === 0) return ""; | 375 if (len === 0) return ""; |
376 return Join(array, len, ',', ConvertToLocaleString); | 376 return Join(array, len, ',', ConvertToLocaleString); |
377 } | 377 } |
378 | 378 |
379 | 379 |
380 function ArrayJoin(separator) { | 380 function ArrayJoin(separator) { |
381 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.join"); | 381 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.join"); |
382 | 382 |
383 var length = TO_UINT32(this.length); | 383 var array = TO_OBJECT_INLINE(this); |
| 384 var length = TO_UINT32(array.length); |
384 if (IS_UNDEFINED(separator)) { | 385 if (IS_UNDEFINED(separator)) { |
385 separator = ','; | 386 separator = ','; |
386 } else if (!IS_STRING(separator)) { | 387 } else if (!IS_STRING(separator)) { |
387 separator = NonStringToString(separator); | 388 separator = NonStringToString(separator); |
388 } | 389 } |
389 | 390 |
390 var result = %_FastAsciiArrayJoin(this, separator); | 391 var result = %_FastAsciiArrayJoin(array, separator); |
391 if (!IS_UNDEFINED(result)) return result; | 392 if (!IS_UNDEFINED(result)) return result; |
392 | 393 |
393 return Join(this, length, separator, ConvertToString); | 394 return Join(array, length, separator, ConvertToString); |
394 } | 395 } |
395 | 396 |
396 | 397 |
397 function ObservedArrayPop(n) { | 398 function ObservedArrayPop(n) { |
398 n--; | 399 n--; |
399 var value = this[n]; | 400 var value = this[n]; |
400 | 401 |
401 try { | 402 try { |
402 BeginPerformSplice(this); | 403 BeginPerformSplice(this); |
403 delete this[n]; | 404 delete this[n]; |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 delete array[high]; | 535 delete array[high]; |
535 } | 536 } |
536 } | 537 } |
537 } | 538 } |
538 } | 539 } |
539 | 540 |
540 | 541 |
541 function ArrayReverse() { | 542 function ArrayReverse() { |
542 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reverse"); | 543 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reverse"); |
543 | 544 |
544 var j = TO_UINT32(this.length) - 1; | 545 var array = TO_OBJECT_INLINE(this); |
| 546 var j = TO_UINT32(array.length) - 1; |
545 | 547 |
546 if (UseSparseVariant(this, j, IS_ARRAY(this))) { | 548 if (UseSparseVariant(array, j, IS_ARRAY(array))) { |
547 SparseReverse(this, j+1); | 549 SparseReverse(array, j+1); |
548 return this; | 550 return array; |
549 } | 551 } |
550 | 552 |
551 for (var i = 0; i < j; i++, j--) { | 553 for (var i = 0; i < j; i++, j--) { |
552 var current_i = this[i]; | 554 var current_i = array[i]; |
553 if (!IS_UNDEFINED(current_i) || i in this) { | 555 if (!IS_UNDEFINED(current_i) || i in array) { |
554 var current_j = this[j]; | 556 var current_j = array[j]; |
555 if (!IS_UNDEFINED(current_j) || j in this) { | 557 if (!IS_UNDEFINED(current_j) || j in array) { |
556 this[i] = current_j; | 558 array[i] = current_j; |
557 this[j] = current_i; | 559 array[j] = current_i; |
558 } else { | 560 } else { |
559 this[j] = current_i; | 561 array[j] = current_i; |
560 delete this[i]; | 562 delete array[i]; |
561 } | 563 } |
562 } else { | 564 } else { |
563 var current_j = this[j]; | 565 var current_j = array[j]; |
564 if (!IS_UNDEFINED(current_j) || j in this) { | 566 if (!IS_UNDEFINED(current_j) || j in array) { |
565 this[i] = current_j; | 567 array[i] = current_j; |
566 delete this[j]; | 568 delete array[j]; |
567 } | 569 } |
568 } | 570 } |
569 } | 571 } |
570 return this; | 572 return array; |
571 } | 573 } |
572 | 574 |
573 | 575 |
574 function ObservedArrayShift(len) { | 576 function ObservedArrayShift(len) { |
575 var first = this[0]; | 577 var first = this[0]; |
576 | 578 |
577 try { | 579 try { |
578 BeginPerformSplice(this); | 580 BeginPerformSplice(this); |
579 SimpleMove(this, 0, 1, len, 0); | 581 SimpleMove(this, 0, 1, len, 0); |
580 this.length = len - 1; | 582 this.length = len - 1; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
661 | 663 |
662 var new_length = len + num_arguments; | 664 var new_length = len + num_arguments; |
663 array.length = new_length; | 665 array.length = new_length; |
664 return new_length; | 666 return new_length; |
665 } | 667 } |
666 | 668 |
667 | 669 |
668 function ArraySlice(start, end) { | 670 function ArraySlice(start, end) { |
669 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.slice"); | 671 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.slice"); |
670 | 672 |
671 var len = TO_UINT32(this.length); | 673 var array = TO_OBJECT_INLINE(this); |
| 674 var len = TO_UINT32(array.length); |
672 var start_i = TO_INTEGER(start); | 675 var start_i = TO_INTEGER(start); |
673 var end_i = len; | 676 var end_i = len; |
674 | 677 |
675 if (!IS_UNDEFINED(end)) end_i = TO_INTEGER(end); | 678 if (!IS_UNDEFINED(end)) end_i = TO_INTEGER(end); |
676 | 679 |
677 if (start_i < 0) { | 680 if (start_i < 0) { |
678 start_i += len; | 681 start_i += len; |
679 if (start_i < 0) start_i = 0; | 682 if (start_i < 0) start_i = 0; |
680 } else { | 683 } else { |
681 if (start_i > len) start_i = len; | 684 if (start_i > len) start_i = len; |
682 } | 685 } |
683 | 686 |
684 if (end_i < 0) { | 687 if (end_i < 0) { |
685 end_i += len; | 688 end_i += len; |
686 if (end_i < 0) end_i = 0; | 689 if (end_i < 0) end_i = 0; |
687 } else { | 690 } else { |
688 if (end_i > len) end_i = len; | 691 if (end_i > len) end_i = len; |
689 } | 692 } |
690 | 693 |
691 var result = []; | 694 var result = []; |
692 | 695 |
693 if (end_i < start_i) return result; | 696 if (end_i < start_i) return result; |
694 | 697 |
695 if (IS_ARRAY(this) && | 698 if (IS_ARRAY(array) && |
696 !%IsObserved(this) && | 699 !%IsObserved(array) && |
697 (end_i > 1000) && | 700 (end_i > 1000) && |
698 (%EstimateNumberOfElements(this) < end_i)) { | 701 (%EstimateNumberOfElements(array) < end_i)) { |
699 SmartSlice(this, start_i, end_i - start_i, len, result); | 702 SmartSlice(array, start_i, end_i - start_i, len, result); |
700 } else { | 703 } else { |
701 SimpleSlice(this, start_i, end_i - start_i, len, result); | 704 SimpleSlice(array, start_i, end_i - start_i, len, result); |
702 } | 705 } |
703 | 706 |
704 result.length = end_i - start_i; | 707 result.length = end_i - start_i; |
705 | 708 |
706 return result; | 709 return result; |
707 } | 710 } |
708 | 711 |
709 | 712 |
710 function ComputeSpliceStartIndex(start_i, len) { | 713 function ComputeSpliceStartIndex(start_i, len) { |
711 if (start_i < 0) { | 714 if (start_i < 0) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
779 } | 782 } |
780 | 783 |
781 | 784 |
782 function ArraySplice(start, delete_count) { | 785 function ArraySplice(start, delete_count) { |
783 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.splice"); | 786 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.splice"); |
784 | 787 |
785 if (%IsObserved(this)) | 788 if (%IsObserved(this)) |
786 return ObservedArraySplice.apply(this, arguments); | 789 return ObservedArraySplice.apply(this, arguments); |
787 | 790 |
788 var num_arguments = %_ArgumentsLength(); | 791 var num_arguments = %_ArgumentsLength(); |
789 var len = TO_UINT32(this.length); | 792 var array = TO_OBJECT_INLINE(this); |
| 793 var len = TO_UINT32(array.length); |
790 var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len); | 794 var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len); |
791 var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len, | 795 var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len, |
792 start_i); | 796 start_i); |
793 var deleted_elements = []; | 797 var deleted_elements = []; |
794 deleted_elements.length = del_count; | 798 deleted_elements.length = del_count; |
795 var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0; | 799 var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0; |
796 | 800 |
797 if (del_count != num_elements_to_add && ObjectIsSealed(this)) { | 801 if (del_count != num_elements_to_add && ObjectIsSealed(array)) { |
798 throw MakeTypeError("array_functions_change_sealed", | 802 throw MakeTypeError("array_functions_change_sealed", |
799 ["Array.prototype.splice"]); | 803 ["Array.prototype.splice"]); |
800 } else if (del_count > 0 && ObjectIsFrozen(this)) { | 804 } else if (del_count > 0 && ObjectIsFrozen(array)) { |
801 throw MakeTypeError("array_functions_on_frozen", | 805 throw MakeTypeError("array_functions_on_frozen", |
802 ["Array.prototype.splice"]); | 806 ["Array.prototype.splice"]); |
803 } | 807 } |
804 | 808 |
805 var use_simple_splice = true; | 809 var use_simple_splice = true; |
806 if (IS_ARRAY(this) && | 810 if (IS_ARRAY(array) && |
807 num_elements_to_add !== del_count) { | 811 num_elements_to_add !== del_count) { |
808 // If we are only deleting/moving a few things near the end of the | 812 // If we are only deleting/moving a few things near the end of the |
809 // array then the simple version is going to be faster, because it | 813 // array then the simple version is going to be faster, because it |
810 // doesn't touch most of the array. | 814 // doesn't touch most of the array. |
811 var estimated_non_hole_elements = %EstimateNumberOfElements(this); | 815 var estimated_non_hole_elements = %EstimateNumberOfElements(array); |
812 if (len > 20 && (estimated_non_hole_elements >> 2) < (len - start_i)) { | 816 if (len > 20 && (estimated_non_hole_elements >> 2) < (len - start_i)) { |
813 use_simple_splice = false; | 817 use_simple_splice = false; |
814 } | 818 } |
815 } | 819 } |
816 | 820 |
817 if (use_simple_splice) { | 821 if (use_simple_splice) { |
818 SimpleSlice(this, start_i, del_count, len, deleted_elements); | 822 SimpleSlice(array, start_i, del_count, len, deleted_elements); |
819 SimpleMove(this, start_i, del_count, len, num_elements_to_add); | 823 SimpleMove(array, start_i, del_count, len, num_elements_to_add); |
820 } else { | 824 } else { |
821 SmartSlice(this, start_i, del_count, len, deleted_elements); | 825 SmartSlice(array, start_i, del_count, len, deleted_elements); |
822 SmartMove(this, start_i, del_count, len, num_elements_to_add); | 826 SmartMove(array, start_i, del_count, len, num_elements_to_add); |
823 } | 827 } |
824 | 828 |
825 // Insert the arguments into the resulting array in | 829 // Insert the arguments into the resulting array in |
826 // place of the deleted elements. | 830 // place of the deleted elements. |
827 var i = start_i; | 831 var i = start_i; |
828 var arguments_index = 2; | 832 var arguments_index = 2; |
829 var arguments_length = %_ArgumentsLength(); | 833 var arguments_length = %_ArgumentsLength(); |
830 while (arguments_index < arguments_length) { | 834 while (arguments_index < arguments_length) { |
831 this[i++] = %_Arguments(arguments_index++); | 835 array[i++] = %_Arguments(arguments_index++); |
832 } | 836 } |
833 this.length = len - del_count + num_elements_to_add; | 837 array.length = len - del_count + num_elements_to_add; |
834 | 838 |
835 // Return the deleted elements. | 839 // Return the deleted elements. |
836 return deleted_elements; | 840 return deleted_elements; |
837 } | 841 } |
838 | 842 |
839 | 843 |
840 function ArraySort(comparefn) { | 844 function ArraySort(comparefn) { |
841 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.sort"); | 845 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.sort"); |
842 | 846 |
843 // In-place QuickSort algorithm. | 847 // In-place QuickSort algorithm. |
(...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1622 )); | 1626 )); |
1623 | 1627 |
1624 SetUpLockedPrototype(InternalPackedArray, $Array(), $Array( | 1628 SetUpLockedPrototype(InternalPackedArray, $Array(), $Array( |
1625 "join", getFunction("join", ArrayJoin), | 1629 "join", getFunction("join", ArrayJoin), |
1626 "pop", getFunction("pop", ArrayPop), | 1630 "pop", getFunction("pop", ArrayPop), |
1627 "push", getFunction("push", ArrayPush) | 1631 "push", getFunction("push", ArrayPush) |
1628 )); | 1632 )); |
1629 } | 1633 } |
1630 | 1634 |
1631 SetUpArray(); | 1635 SetUpArray(); |
OLD | NEW |