Changeset 197192 in webkit for trunk/Source/JavaScriptCore/runtime
- Timestamp:
- Feb 26, 2016, 12:25:42 PM (9 years ago)
- Location:
- trunk/Source/JavaScriptCore/runtime
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/runtime/JSDataView.cpp
r191215 r197192 79 79 } 80 80 81 bool JSDataView::set(ExecState*, JSObject*, unsigned, unsigned)81 bool JSDataView::set(ExecState*, unsigned, JSObject*, unsigned, unsigned) 82 82 { 83 83 UNREACHABLE_FOR_PLATFORM(); -
trunk/Source/JavaScriptCore/runtime/JSDataView.h
r191215 r197192 49 49 static JSDataView* createUninitialized(ExecState*, Structure*, unsigned length); 50 50 static JSDataView* create(ExecState*, Structure*, unsigned length); 51 bool set(ExecState*, JSObject*, unsigned offset, unsigned length);51 bool set(ExecState*, unsigned, JSObject*, unsigned, unsigned length); 52 52 bool setIndex(ExecState*, unsigned, JSValue); 53 53 -
trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayView.h
r195701 r197192 84 84 // }; 85 85 86 enum class CopyType { 87 LeftToRight, 88 Unobservable, 89 }; 90 86 91 template<typename Adaptor> 87 92 class JSGenericTypedArrayView : public JSArrayBufferView { … … 218 223 // appropriate exception. 219 224 bool validateRange(ExecState*, unsigned offset, unsigned length); 220 225 221 226 // Returns true if successful, and false on error; if it returns false 222 227 // then it will have thrown an exception. 223 bool set(ExecState*, JSObject*, unsigned offset, unsigned length);228 bool set(ExecState*, unsigned offset, JSObject*, unsigned objectOffset, unsigned length, CopyType type = CopyType::Unobservable); 224 229 225 230 PassRefPtr<typename Adaptor::ViewType> typedImpl() … … 292 297 template<typename OtherAdaptor> 293 298 bool setWithSpecificType( 294 ExecState*, JSGenericTypedArrayView<OtherAdaptor>*,295 unsigned o ffset, unsigned length);299 ExecState*, unsigned offset, JSGenericTypedArrayView<OtherAdaptor>*, 300 unsigned objectOffset, unsigned length, CopyType); 296 301 297 302 // The ECMA 6 spec states that floating point Typed Arrays should have the following ordering: -
trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewConstructorInlines.h
r196986 r197192 78 78 79 79 template<typename ViewClass> 80 staticJSObject* constructGenericTypedArrayViewFromIterator(ExecState* exec, Structure* structure, JSValue iterator)80 inline JSObject* constructGenericTypedArrayViewFromIterator(ExecState* exec, Structure* structure, JSValue iterator) 81 81 { 82 82 if (!iterator.isObject()) … … 116 116 117 117 template<typename ViewClass> 118 staticJSObject* constructGenericTypedArrayViewWithArguments(ExecState* exec, Structure* structure, EncodedJSValue firstArgument, unsigned offset, Optional<unsigned> lengthOpt)118 inline JSObject* constructGenericTypedArrayViewWithArguments(ExecState* exec, Structure* structure, EncodedJSValue firstArgument, unsigned offset, Optional<unsigned> lengthOpt) 119 119 { 120 120 JSValue firstValue = JSValue::decode(firstArgument); … … 194 194 } 195 195 196 if (!result->set(exec, object, 0, length))196 if (!result->set(exec, 0, object, 0, length)) 197 197 return nullptr; 198 198 … … 217 217 218 218 template<typename ViewClass> 219 static EncodedJSValue JSC_HOST_CALL constructGenericTypedArrayView(ExecState* exec) 219 EncodedJSValue JSC_HOST_CALL constructGenericTypedArrayView(ExecState*); 220 221 template<typename ViewClass> 222 EncodedJSValue JSC_HOST_CALL constructGenericTypedArrayView(ExecState* exec) 220 223 { 221 224 Structure* structure = InternalFunction::createSubclassStructure(exec, exec->newTarget(), asInternalFunction(exec->callee())->globalObject()->typedArrayStructure(ViewClass::TypedArrayStorageType)); -
trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h
r196179 r197192 139 139 template<typename OtherAdaptor> 140 140 bool JSGenericTypedArrayView<Adaptor>::setWithSpecificType( 141 ExecState* exec, JSGenericTypedArrayView<OtherAdaptor>* other,142 unsigned o ffset, unsigned length)141 ExecState* exec, unsigned offset, JSGenericTypedArrayView<OtherAdaptor>* other, 142 unsigned otherOffset, unsigned length, CopyType type) 143 143 { 144 144 // Handle the hilarious case: the act of getting the length could have resulted … … 149 149 // but we won't have a security vulnerability. 150 150 length = std::min(length, other->length()); 151 151 152 RELEASE_ASSERT(other->canAccessRangeQuickly(otherOffset, length)); 152 153 if (!validateRange(exec, offset, length)) 153 154 return false; 154 155 if (other->length() != length) {156 exec->vm().throwException(exec, createRangeError(exec, "Length of incoming array changed unexpectedly."));157 return false;158 }159 155 160 156 // This method doesn't support copying between the same array. Note that … … 186 182 187 183 unsigned otherElementSize = sizeof(typename OtherAdaptor::Type); 188 189 // Handle cases (1) and (2 B).184 185 // Handle cases (1) and (2A). 190 186 if (!hasArrayBuffer() || !other->hasArrayBuffer() 191 187 || existingBuffer() != other->existingBuffer() 192 || (elementSize == otherElementSize && vector() > other->vector())) { 188 || (elementSize == otherElementSize && vector() <= other->vector()) 189 || type == CopyType::LeftToRight) { 190 for (unsigned i = 0; i < length; ++i) { 191 setIndexQuicklyToNativeValue( 192 offset + i, OtherAdaptor::template convertTo<Adaptor>( 193 other->getIndexQuicklyAsNativeValue(i + otherOffset))); 194 } 195 return true; 196 } 197 198 // Now we either have (2B) or (3) - so first we try to cover (2B). 199 if (elementSize == otherElementSize) { 193 200 for (unsigned i = length; i--;) { 194 201 setIndexQuicklyToNativeValue( 195 202 offset + i, OtherAdaptor::template convertTo<Adaptor>( 196 other->getIndexQuicklyAsNativeValue(i))); 197 } 198 return true; 199 } 200 201 // Now we either have (2A) or (3) - so first we try to cover (2A). 202 if (elementSize == otherElementSize) { 203 for (unsigned i = 0; i < length; ++i) { 204 setIndexQuicklyToNativeValue( 205 offset + i, OtherAdaptor::template convertTo<Adaptor>( 206 other->getIndexQuicklyAsNativeValue(i))); 203 other->getIndexQuicklyAsNativeValue(i + otherOffset))); 207 204 } 208 205 return true; … … 213 210 for (unsigned i = length; i--;) { 214 211 transferBuffer[i] = OtherAdaptor::template convertTo<Adaptor>( 215 other->getIndexQuicklyAsNativeValue(i ));212 other->getIndexQuicklyAsNativeValue(i + otherOffset)); 216 213 } 217 214 for (unsigned i = length; i--;) … … 223 220 template<typename Adaptor> 224 221 bool JSGenericTypedArrayView<Adaptor>::set( 225 ExecState* exec, JSObject* object, unsigned offset, unsigned length)222 ExecState* exec, unsigned offset, JSObject* object, unsigned objectOffset, unsigned length, CopyType type) 226 223 { 227 224 const ClassInfo* ci = object->classInfo(); … … 231 228 length = std::min(length, other->length()); 232 229 230 RELEASE_ASSERT(other->canAccessRangeQuickly(objectOffset, length)); 233 231 if (!validateRange(exec, offset, length)) 234 232 return false; 235 236 memmove(typedVector() + offset, other->typedVector() , other->byteLength());233 234 memmove(typedVector() + offset, other->typedVector() + objectOffset, other->byteLength()); 237 235 return true; 238 236 } … … 241 239 case TypeInt8: 242 240 return setWithSpecificType<Int8Adaptor>( 243 exec, jsCast<JSInt8Array*>(object), offset, length);241 exec, offset, jsCast<JSInt8Array*>(object), objectOffset, length, type); 244 242 case TypeInt16: 245 243 return setWithSpecificType<Int16Adaptor>( 246 exec, jsCast<JSInt16Array*>(object), offset, length);244 exec, offset, jsCast<JSInt16Array*>(object), objectOffset, length, type); 247 245 case TypeInt32: 248 246 return setWithSpecificType<Int32Adaptor>( 249 exec, jsCast<JSInt32Array*>(object), offset, length);247 exec, offset, jsCast<JSInt32Array*>(object), objectOffset, length, type); 250 248 case TypeUint8: 251 249 return setWithSpecificType<Uint8Adaptor>( 252 exec, jsCast<JSUint8Array*>(object), offset, length);250 exec, offset, jsCast<JSUint8Array*>(object), objectOffset, length, type); 253 251 case TypeUint8Clamped: 254 252 return setWithSpecificType<Uint8ClampedAdaptor>( 255 exec, jsCast<JSUint8ClampedArray*>(object), offset, length);253 exec, offset, jsCast<JSUint8ClampedArray*>(object), objectOffset, length, type); 256 254 case TypeUint16: 257 255 return setWithSpecificType<Uint16Adaptor>( 258 exec, jsCast<JSUint16Array*>(object), offset, length);256 exec, offset, jsCast<JSUint16Array*>(object), objectOffset, length, type); 259 257 case TypeUint32: 260 258 return setWithSpecificType<Uint32Adaptor>( 261 exec, jsCast<JSUint32Array*>(object), offset, length);259 exec, offset, jsCast<JSUint32Array*>(object), objectOffset, length, type); 262 260 case TypeFloat32: 263 261 return setWithSpecificType<Float32Adaptor>( 264 exec, jsCast<JSFloat32Array*>(object), offset, length);262 exec, offset, jsCast<JSFloat32Array*>(object), objectOffset, length, type); 265 263 case TypeFloat64: 266 264 return setWithSpecificType<Float64Adaptor>( 267 exec, jsCast<JSFloat64Array*>(object), offset, length);265 exec, offset, jsCast<JSFloat64Array*>(object), objectOffset, length, type); 268 266 case NotTypedArray: 269 267 case TypeDataView: { 270 268 if (!validateRange(exec, offset, length)) 271 269 return false; 270 272 271 // We could optimize this case. But right now, we don't. 273 272 for (unsigned i = 0; i < length; ++i) { 274 JSValue value = object->get(exec, i );273 JSValue value = object->get(exec, i + objectOffset); 275 274 if (!setIndex(exec, offset + i, value)) 276 275 return false; -
trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewPrototypeFunctions.h
r195416 r197192 46 46 static const char* typedArrayBufferHasBeenDetachedErrorMessage = "Underlying ArrayBuffer has been detached from the view"; 47 47 48 // This implements 22.2.4.7 TypedArraySpeciesCreate 49 // Note, that this function throws. 50 template<typename Functor> 51 inline JSArrayBufferView* speciesConstruct(ExecState* exec, JSObject* exemplar, MarkedArgumentBuffer& args, const Functor& defaultConstructor) 52 { 53 JSValue constructor = exemplar->get(exec, exec->propertyNames().constructor); 54 if (exec->hadException()) 55 return nullptr; 56 57 if (constructor.isUndefined()) 58 return defaultConstructor(); 59 if (!constructor.isObject()) { 60 throwTypeError(exec, "constructor Property should not be null"); 61 return nullptr; 62 } 63 64 JSValue species = constructor.get(exec, exec->propertyNames().speciesSymbol); 65 if (exec->hadException()) 66 return nullptr; 67 68 if (species.isUndefinedOrNull()) 69 return defaultConstructor(); 70 71 JSValue result = construct(exec, species, args, "species is not a constructor"); 72 if (exec->hadException()) 73 return nullptr; 74 75 if (JSArrayBufferView* view = jsDynamicCast<JSArrayBufferView*>(result)) 76 return view; 77 78 throwTypeError(exec, "species constructor did not return a TypedArray View"); 79 return nullptr; 80 } 81 48 82 inline unsigned argumentClampedIndexFromStartOrEnd(ExecState* exec, int argument, unsigned length, unsigned undefinedValue = 0) 49 83 { … … 100 134 return JSValue::encode(jsUndefined()); 101 135 102 thisObject->set(exec, sourceArray, offset, length);136 thisObject->set(exec, offset, sourceArray, 0, length, CopyType::Unobservable); 103 137 return JSValue::encode(jsUndefined()); 104 138 } … … 364 398 unsigned length = end - begin; 365 399 366 typename ViewClass::ElementType* array = thisObject->typedVector(); 367 368 Structure* structure = 369 callee->globalObject()->typedArrayStructure(ViewClass::TypedArrayStorageType); 370 371 ViewClass* result = ViewClass::createUninitialized(exec, structure, length); 372 373 // We can use memcpy since we know this a new buffer 374 memcpy(static_cast<void*>(result->typedVector()), static_cast<void*>(array + begin), length * thisObject->elementSize); 400 MarkedArgumentBuffer args; 401 args.append(jsNumber(length)); 402 403 JSArrayBufferView* result = speciesConstruct(exec, thisObject, args, [&]() { 404 Structure* structure = callee->globalObject()->typedArrayStructure(ViewClass::TypedArrayStorageType); 405 return ViewClass::createUninitialized(exec, structure, length); 406 }); 407 if (exec->hadException()) 408 return JSValue::encode(JSValue()); 409 410 // We return early here since we don't allocate a backing store if length is 0 and memmove does not like nullptrs 411 if (!length) 412 return JSValue::encode(result); 413 414 // The species constructor may return an array with any arbitrary length. 415 length = std::min(length, result->length()); 416 switch (result->classInfo()->typedArrayStorageType) { 417 case TypeInt8: 418 jsCast<JSInt8Array*>(result)->set(exec, 0, thisObject, begin, length, CopyType::LeftToRight); 419 break; 420 case TypeInt16: 421 jsCast<JSInt16Array*>(result)->set(exec, 0, thisObject, begin, length, CopyType::LeftToRight); 422 break; 423 case TypeInt32: 424 jsCast<JSInt32Array*>(result)->set(exec, 0, thisObject, begin, length, CopyType::LeftToRight); 425 break; 426 case TypeUint8: 427 jsCast<JSUint8Array*>(result)->set(exec, 0, thisObject, begin, length, CopyType::LeftToRight); 428 break; 429 case TypeUint8Clamped: 430 jsCast<JSUint8ClampedArray*>(result)->set(exec, 0, thisObject, begin, length, CopyType::LeftToRight); 431 break; 432 case TypeUint16: 433 jsCast<JSUint16Array*>(result)->set(exec, 0, thisObject, begin, length, CopyType::LeftToRight); 434 break; 435 case TypeUint32: 436 jsCast<JSUint32Array*>(result)->set(exec, 0, thisObject, begin, length, CopyType::LeftToRight); 437 break; 438 case TypeFloat32: 439 jsCast<JSFloat32Array*>(result)->set(exec, 0, thisObject, begin, length, CopyType::LeftToRight); 440 break; 441 case TypeFloat64: 442 jsCast<JSFloat64Array*>(result)->set(exec, 0, thisObject, begin, length, CopyType::LeftToRight); 443 break; 444 default: 445 RELEASE_ASSERT_NOT_REACHED(); 446 } 375 447 376 448 return JSValue::encode(result); … … 406 478 RELEASE_ASSERT(thisLength == thisObject->length()); 407 479 408 Structure* structure = 409 callee->globalObject()->typedArrayStructure(ViewClass::TypedArrayStorageType); 410 411 ViewClass* result = ViewClass::create( 412 exec, structure, arrayBuffer, 413 thisObject->byteOffset() + offset * ViewClass::elementSize, 414 length); 480 unsigned newByteOffset = thisObject->byteOffset() + offset * ViewClass::elementSize; 481 482 MarkedArgumentBuffer args; 483 args.append(exec->vm().m_typedArrayController->toJS(exec, thisObject->globalObject(), thisObject->buffer())); 484 args.append(jsNumber(newByteOffset)); 485 args.append(jsNumber(length)); 486 487 JSArrayBufferView* result = speciesConstruct(exec, thisObject, args, [&]() { 488 Structure* structure = callee->globalObject()->typedArrayStructure(ViewClass::TypedArrayStorageType); 489 490 return ViewClass::create( 491 exec, structure, arrayBuffer, 492 thisObject->byteOffset() + offset * ViewClass::elementSize, 493 length); 494 }); 495 if (exec->hadException()) 496 return JSValue::encode(JSValue()); 415 497 416 498 return JSValue::encode(result);
Note:
See TracChangeset
for help on using the changeset viewer.