Changeset 222675 in webkit for trunk/Source/JavaScriptCore/runtime/JSArrayInlines.h
- Timestamp:
- Sep 29, 2017, 6:16:52 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/runtime/JSArrayInlines.h
r222658 r222675 20 20 #pragma once 21 21 22 #include "Error.h" 22 23 #include "JSArray.h" 23 24 #include "JSCellInlines.h" … … 83 84 } 84 85 86 ALWAYS_INLINE void JSArray::pushInline(ExecState* exec, JSValue value) 87 { 88 VM& vm = exec->vm(); 89 auto scope = DECLARE_THROW_SCOPE(vm); 90 91 Butterfly* butterfly = m_butterfly.getMayBeNull(); 92 93 switch (indexingType()) { 94 case ArrayClass: { 95 createInitialUndecided(vm, 0); 96 FALLTHROUGH; 97 } 98 99 case ArrayWithUndecided: { 100 convertUndecidedForValue(vm, value); 101 scope.release(); 102 push(exec, value); 103 return; 104 } 105 106 case ArrayWithInt32: { 107 if (!value.isInt32()) { 108 convertInt32ForValue(vm, value); 109 scope.release(); 110 push(exec, value); 111 return; 112 } 113 114 unsigned length = butterfly->publicLength(); 115 ASSERT(length <= butterfly->vectorLength()); 116 if (length < butterfly->vectorLength()) { 117 butterfly->contiguousInt32()[length].setWithoutWriteBarrier(value); 118 butterfly->setPublicLength(length + 1); 119 return; 120 } 121 122 if (UNLIKELY(length > MAX_ARRAY_INDEX)) { 123 methodTable(vm)->putByIndex(this, exec, length, value, true); 124 if (!scope.exception()) 125 throwException(exec, scope, createRangeError(exec, ASCIILiteral(LengthExceededTheMaximumArrayLengthError))); 126 return; 127 } 128 129 scope.release(); 130 putByIndexBeyondVectorLengthWithoutAttributes<Int32Shape>(exec, length, value); 131 return; 132 } 133 134 case ArrayWithContiguous: { 135 unsigned length = butterfly->publicLength(); 136 ASSERT(length <= butterfly->vectorLength()); 137 if (length < butterfly->vectorLength()) { 138 butterfly->contiguous()[length].set(vm, this, value); 139 butterfly->setPublicLength(length + 1); 140 return; 141 } 142 143 if (UNLIKELY(length > MAX_ARRAY_INDEX)) { 144 methodTable(vm)->putByIndex(this, exec, length, value, true); 145 if (!scope.exception()) 146 throwException(exec, scope, createRangeError(exec, ASCIILiteral(LengthExceededTheMaximumArrayLengthError))); 147 return; 148 } 149 150 scope.release(); 151 putByIndexBeyondVectorLengthWithoutAttributes<ContiguousShape>(exec, length, value); 152 return; 153 } 154 155 case ArrayWithDouble: { 156 if (!value.isNumber()) { 157 convertDoubleToContiguous(vm); 158 scope.release(); 159 push(exec, value); 160 return; 161 } 162 double valueAsDouble = value.asNumber(); 163 if (valueAsDouble != valueAsDouble) { 164 convertDoubleToContiguous(vm); 165 scope.release(); 166 push(exec, value); 167 return; 168 } 169 170 unsigned length = butterfly->publicLength(); 171 ASSERT(length <= butterfly->vectorLength()); 172 if (length < butterfly->vectorLength()) { 173 butterfly->contiguousDouble()[length] = valueAsDouble; 174 butterfly->setPublicLength(length + 1); 175 return; 176 } 177 178 if (UNLIKELY(length > MAX_ARRAY_INDEX)) { 179 methodTable(vm)->putByIndex(this, exec, length, value, true); 180 if (!scope.exception()) 181 throwException(exec, scope, createRangeError(exec, ASCIILiteral(LengthExceededTheMaximumArrayLengthError))); 182 return; 183 } 184 185 scope.release(); 186 putByIndexBeyondVectorLengthWithoutAttributes<DoubleShape>(exec, length, value); 187 return; 188 } 189 190 case ArrayWithSlowPutArrayStorage: { 191 unsigned oldLength = length(); 192 bool putResult = false; 193 if (attemptToInterceptPutByIndexOnHole(exec, oldLength, value, true, putResult)) { 194 if (!scope.exception() && oldLength < 0xFFFFFFFFu) { 195 scope.release(); 196 setLength(exec, oldLength + 1, true); 197 } 198 return; 199 } 200 FALLTHROUGH; 201 } 202 203 case ArrayWithArrayStorage: { 204 ArrayStorage* storage = butterfly->arrayStorage(); 205 206 // Fast case - push within vector, always update m_length & m_numValuesInVector. 207 unsigned length = storage->length(); 208 if (length < storage->vectorLength()) { 209 storage->m_vector[length].set(vm, this, value); 210 storage->setLength(length + 1); 211 ++storage->m_numValuesInVector; 212 return; 213 } 214 215 // Pushing to an array of invalid length (2^31-1) stores the property, but throws a range error. 216 if (UNLIKELY(storage->length() > MAX_ARRAY_INDEX)) { 217 methodTable(vm)->putByIndex(this, exec, storage->length(), value, true); 218 // Per ES5.1 15.4.4.7 step 6 & 15.4.5.1 step 3.d. 219 if (!scope.exception()) 220 throwException(exec, scope, createRangeError(exec, ASCIILiteral(LengthExceededTheMaximumArrayLengthError))); 221 return; 222 } 223 224 // Handled the same as putIndex. 225 scope.release(); 226 putByIndexBeyondVectorLengthWithArrayStorage(exec, storage->length(), value, true, storage); 227 return; 228 } 229 230 default: 231 RELEASE_ASSERT_NOT_REACHED(); 232 } 233 } 234 85 235 } // namespace JSC
Note:
See TracChangeset
for help on using the changeset viewer.