| 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 |