Changeset 222563 in webkit for trunk/Source/JavaScriptCore/runtime/JSArray.cpp
- Timestamp:
- Sep 27, 2017, 11:37:41 AM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/runtime/JSArray.cpp
r222473 r222563 41 41 namespace JSC { 42 42 43 staticconst char* const LengthExceededTheMaximumArrayLengthError = "Length exceeded the maximum array length";43 const char* const LengthExceededTheMaximumArrayLengthError = "Length exceeded the maximum array length"; 44 44 45 45 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSArray); … … 726 726 // - we always are writing beyond the current array bounds, so it is always necessary to update m_length & m_numValuesInVector. 727 727 // - pushing to an array of length 2^32-1 stores the property, but throws a range error. 728 void JSArray::push(ExecState* exec, JSValue value) 729 { 730 VM& vm = exec->vm(); 731 auto scope = DECLARE_THROW_SCOPE(vm); 732 733 Butterfly* butterfly = m_butterfly.getMayBeNull(); 734 735 switch (indexingType()) { 736 case ArrayClass: { 737 createInitialUndecided(vm, 0); 738 FALLTHROUGH; 739 } 740 741 case ArrayWithUndecided: { 742 convertUndecidedForValue(vm, value); 743 scope.release(); 744 push(exec, value); 745 return; 746 } 747 748 case ArrayWithInt32: { 749 if (!value.isInt32()) { 750 convertInt32ForValue(vm, value); 751 scope.release(); 752 push(exec, value); 753 return; 754 } 755 756 unsigned length = butterfly->publicLength(); 757 ASSERT(length <= butterfly->vectorLength()); 758 if (length < butterfly->vectorLength()) { 759 butterfly->contiguousInt32()[length].setWithoutWriteBarrier(value); 760 butterfly->setPublicLength(length + 1); 761 return; 762 } 763 764 if (UNLIKELY(length > MAX_ARRAY_INDEX)) { 765 methodTable(vm)->putByIndex(this, exec, length, value, true); 766 if (!scope.exception()) 767 throwException(exec, scope, createRangeError(exec, ASCIILiteral(LengthExceededTheMaximumArrayLengthError))); 768 return; 769 } 770 771 scope.release(); 772 putByIndexBeyondVectorLengthWithoutAttributes<Int32Shape>(exec, length, value); 773 return; 774 } 775 776 case ArrayWithContiguous: { 777 unsigned length = butterfly->publicLength(); 778 ASSERT(length <= butterfly->vectorLength()); 779 if (length < butterfly->vectorLength()) { 780 butterfly->contiguous()[length].set(vm, this, value); 781 butterfly->setPublicLength(length + 1); 782 return; 783 } 784 785 if (UNLIKELY(length > MAX_ARRAY_INDEX)) { 786 methodTable(vm)->putByIndex(this, exec, length, value, true); 787 if (!scope.exception()) 788 throwException(exec, scope, createRangeError(exec, ASCIILiteral(LengthExceededTheMaximumArrayLengthError))); 789 return; 790 } 791 792 scope.release(); 793 putByIndexBeyondVectorLengthWithoutAttributes<ContiguousShape>(exec, length, value); 794 return; 795 } 796 797 case ArrayWithDouble: { 798 if (!value.isNumber()) { 799 convertDoubleToContiguous(vm); 800 scope.release(); 801 push(exec, value); 802 return; 803 } 804 double valueAsDouble = value.asNumber(); 805 if (valueAsDouble != valueAsDouble) { 806 convertDoubleToContiguous(vm); 807 scope.release(); 808 push(exec, value); 809 return; 810 } 811 812 unsigned length = butterfly->publicLength(); 813 ASSERT(length <= butterfly->vectorLength()); 814 if (length < butterfly->vectorLength()) { 815 butterfly->contiguousDouble()[length] = valueAsDouble; 816 butterfly->setPublicLength(length + 1); 817 return; 818 } 819 820 if (UNLIKELY(length > MAX_ARRAY_INDEX)) { 821 methodTable(vm)->putByIndex(this, exec, length, value, true); 822 if (!scope.exception()) 823 throwException(exec, scope, createRangeError(exec, ASCIILiteral(LengthExceededTheMaximumArrayLengthError))); 824 return; 825 } 826 827 scope.release(); 828 putByIndexBeyondVectorLengthWithoutAttributes<DoubleShape>(exec, length, value); 829 return; 830 } 831 832 case ArrayWithSlowPutArrayStorage: { 833 unsigned oldLength = length(); 834 bool putResult = false; 835 if (attemptToInterceptPutByIndexOnHole(exec, oldLength, value, true, putResult)) { 836 if (!scope.exception() && oldLength < 0xFFFFFFFFu) { 837 scope.release(); 838 setLength(exec, oldLength + 1, true); 839 } 840 return; 841 } 842 FALLTHROUGH; 843 } 844 845 case ArrayWithArrayStorage: { 846 ArrayStorage* storage = butterfly->arrayStorage(); 847 848 // Fast case - push within vector, always update m_length & m_numValuesInVector. 849 unsigned length = storage->length(); 850 if (length < storage->vectorLength()) { 851 storage->m_vector[length].set(vm, this, value); 852 storage->setLength(length + 1); 853 ++storage->m_numValuesInVector; 854 return; 855 } 856 857 // Pushing to an array of invalid length (2^31-1) stores the property, but throws a range error. 858 if (UNLIKELY(storage->length() > MAX_ARRAY_INDEX)) { 859 methodTable(vm)->putByIndex(this, exec, storage->length(), value, true); 860 // Per ES5.1 15.4.4.7 step 6 & 15.4.5.1 step 3.d. 861 if (!scope.exception()) 862 throwException(exec, scope, createRangeError(exec, ASCIILiteral(LengthExceededTheMaximumArrayLengthError))); 863 return; 864 } 865 866 // Handled the same as putIndex. 867 scope.release(); 868 putByIndexBeyondVectorLengthWithArrayStorage(exec, storage->length(), value, true, storage); 869 return; 870 } 871 872 default: 873 RELEASE_ASSERT_NOT_REACHED(); 874 } 728 NEVER_INLINE void JSArray::push(ExecState* exec, JSValue value) 729 { 730 pushInline(exec, value); 875 731 } 876 732
Note:
See TracChangeset
for help on using the changeset viewer.