EncodedJSValue getData(ExecState* exec) { JSDataView* dataView = jsDynamicCast<JSDataView*>(exec->thisValue()); if (!dataView) return throwVMError(exec, createTypeError(exec, "Receiver of DataView method must be a DataView")); if (!exec->argumentCount()) return throwVMError(exec, createTypeError(exec, "Need at least one argument (the byteOffset)")); unsigned byteOffset = exec->uncheckedArgument(0).toUInt32(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); bool littleEndian = false; unsigned elementSize = sizeof(typename Adaptor::Type); if (elementSize > 1 && exec->argumentCount() >= 2) { littleEndian = exec->uncheckedArgument(1).toBoolean(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); } unsigned byteLength = dataView->length(); if (elementSize > byteLength || byteOffset > byteLength - elementSize) return throwVMError(exec, createRangeError(exec, "Out of bounds access")); typename Adaptor::Type value = *reinterpret_cast<typename Adaptor::Type*>(static_cast<uint8_t*>(dataView->vector()) + byteOffset); if (needToFlipBytesIfLittleEndian(littleEndian)) value = flipBytes(value); return JSValue::encode(Adaptor::toJSValue(value)); }
EncodedJSValue setData(ExecState* exec) { JSDataView* dataView = jsDynamicCast<JSDataView*>(exec->thisValue()); if (!dataView) return throwVMError(exec, createTypeError(exec, "Receiver of DataView method must be a DataView")); if (exec->argumentCount() < 2) return throwVMError(exec, createTypeError(exec, "Need at least two argument (the byteOffset and value)")); unsigned byteOffset = exec->uncheckedArgument(0).toUInt32(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); const unsigned dataSize = sizeof(typename Adaptor::Type); union { typename Adaptor::Type value; uint8_t rawBytes[dataSize]; } u; u.value = toNativeFromValue<Adaptor>(exec, exec->uncheckedArgument(1)); if (exec->hadException()) return JSValue::encode(jsUndefined()); bool littleEndian = false; unsigned elementSize = sizeof(typename Adaptor::Type); if (elementSize > 1 && exec->argumentCount() >= 3) { littleEndian = exec->uncheckedArgument(2).toBoolean(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); } unsigned byteLength = dataView->length(); if (elementSize > byteLength || byteOffset > byteLength - elementSize) return throwVMError(exec, createRangeError(exec, "Out of bounds access")); uint8_t* dataPtr = static_cast<uint8_t*>(dataView->vector()) + byteOffset; if (needToFlipBytesIfLittleEndian(littleEndian)) { for (unsigned i = dataSize; i--;) *dataPtr++ = u.rawBytes[i]; } else { for (unsigned i = 0; i < dataSize; i++) *dataPtr++ = u.rawBytes[i]; } return JSValue::encode(jsUndefined()); }
EncodedJSValue setData(ExecState* exec) { VM& vm = exec->vm(); auto scope = DECLARE_THROW_SCOPE(vm); JSDataView* dataView = jsDynamicCast<JSDataView*>(exec->thisValue()); if (!dataView) return throwVMTypeError(exec, scope, ASCIILiteral("Receiver of DataView method must be a DataView")); unsigned byteOffset = exec->argument(0).toIndex(exec, "byteOffset"); RETURN_IF_EXCEPTION(scope, encodedJSValue()); const unsigned dataSize = sizeof(typename Adaptor::Type); union { typename Adaptor::Type value; uint8_t rawBytes[dataSize]; } u; u.value = toNativeFromValue<Adaptor>(exec, exec->argument(1)); RETURN_IF_EXCEPTION(scope, encodedJSValue()); bool littleEndian = false; unsigned elementSize = sizeof(typename Adaptor::Type); if (elementSize > 1 && exec->argumentCount() >= 3) { littleEndian = exec->uncheckedArgument(2).toBoolean(exec); RETURN_IF_EXCEPTION(scope, encodedJSValue()); } unsigned byteLength = dataView->length(); if (elementSize > byteLength || byteOffset > byteLength - elementSize) return throwVMError(exec, scope, createRangeError(exec, ASCIILiteral("Out of bounds access"))); uint8_t* dataPtr = static_cast<uint8_t*>(dataView->vector()) + byteOffset; if (needToFlipBytesIfLittleEndian(littleEndian)) { for (unsigned i = dataSize; i--;) *dataPtr++ = u.rawBytes[i]; } else { for (unsigned i = 0; i < dataSize; i++) *dataPtr++ = u.rawBytes[i]; } return JSValue::encode(jsUndefined()); }