Example #1
0
EncodedJSValue JSC_HOST_CALL jsDataViewPrototypeFunctionSetFloat64(ExecState* exec)
{
    JSValue thisValue = exec->hostThisValue();
    if (!thisValue.inherits(&JSDataView::s_info))
        return throwVMTypeError(exec);
    JSDataView* castedThis = static_cast<JSDataView*>(asObject(thisValue));
    ASSERT_GC_OBJECT_INHERITS(castedThis, &JSDataView::s_info);
    DataView* imp = static_cast<DataView*>(castedThis->impl());
    if (exec->argumentCount() < 2)
        return throwVMError(exec, createSyntaxError(exec, "Not enough arguments"));
    ExceptionCode ec = 0;
    unsigned byteOffset(exec->argument(0).toUInt32(exec));
    if (exec->hadException())
        return JSValue::encode(jsUndefined());
    double value(exec->argument(1).toNumber(exec));
    if (exec->hadException())
        return JSValue::encode(jsUndefined());

    int argsCount = exec->argumentCount();
    if (argsCount <= 2) {
        imp->setFloat64(byteOffset, value, ec);
        setDOMException(exec, ec);
        return JSValue::encode(jsUndefined());
    }

    bool littleEndian(exec->argument(2).toBoolean(exec));
    if (exec->hadException())
        return JSValue::encode(jsUndefined());

    imp->setFloat64(byteOffset, value, littleEndian, ec);
    setDOMException(exec, ec);
    return JSValue::encode(jsUndefined());
}
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));
}
Example #3
0
EncodedJSValue JSC_HOST_CALL jsDataViewPrototypeFunctionSetUint8(ExecState* exec)
{
    JSValue thisValue = exec->hostThisValue();
    if (!thisValue.inherits(&JSDataView::s_info))
        return throwVMTypeError(exec);
    JSDataView* castedThis = static_cast<JSDataView*>(asObject(thisValue));
    ASSERT_GC_OBJECT_INHERITS(castedThis, &JSDataView::s_info);
    return JSValue::encode(castedThis->setUint8(exec));
}
Example #4
0
EncodedJSValue JSC_HOST_CALL dataViewProtoGetterByteOffset(ExecState* exec)
{
    VM& vm = exec->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    JSDataView* view = jsDynamicCast<JSDataView*>(exec->thisValue());
    if (!view)
        return throwVMTypeError(exec, scope, "DataView.prototype.buffer expects |this| to be a DataView object");

    return JSValue::encode(jsNumber(view->byteOffset()));
}
Example #5
0
bool JSDataView::getOwnPropertySlot(
    JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
{
    JSDataView* thisObject = jsCast<JSDataView*>(object);
    if (propertyName == exec->propertyNames().byteLength) {
        slot.setValue(thisObject, DontEnum | ReadOnly, jsNumber(thisObject->m_length));
        return true;
    }
    if (propertyName == exec->propertyNames().byteOffset) {
        slot.setValue(thisObject, DontEnum | ReadOnly, jsNumber(thisObject->byteOffset()));
        return true;
    }

    return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
}
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());
}
Example #7
0
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());
}
Example #8
0
JSDataView* JSDataView::create(
    ExecState* exec, Structure* structure, PassRefPtr<ArrayBuffer> passedBuffer,
    unsigned byteOffset, unsigned byteLength)
{
    RefPtr<ArrayBuffer> buffer = passedBuffer;
    if (!ArrayBufferView::verifySubRange<uint8_t>(buffer, byteOffset, byteLength)) {
        throwVMError(
            exec, createRangeError(exec, "Byte offset and length out of range of buffer"));
        return 0;
    }
    VM& vm = exec->vm();
    ConstructionContext context(
        structure, buffer, byteOffset, byteLength, ConstructionContext::DataView);
    ASSERT(context);
    JSDataView* result =
        new (NotNull, allocateCell<JSDataView>(vm.heap)) JSDataView(vm, context, buffer.get());
    result->finishCreation(vm);
    return result;
}
Example #9
0
JSDataView* JSDataView::create(
    ExecState* exec, Structure* structure, PassRefPtr<ArrayBuffer> passedBuffer,
    unsigned byteOffset, unsigned byteLength)
{
    RefPtr<ArrayBuffer> buffer = passedBuffer;
    if (!ArrayBufferView::verifySubRangeLength(buffer, byteOffset, byteLength, sizeof(uint8_t))) {
        throwVMError(exec, createRangeError(exec, ASCIILiteral("Length out of range of buffer")));
        return nullptr;
    }
    if (!ArrayBufferView::verifyByteOffsetAlignment(byteOffset, sizeof(uint8_t))) {
        exec->vm().throwException(exec, createRangeError(exec, ASCIILiteral("Byte offset is not aligned")));
        return nullptr;
    }
    VM& vm = exec->vm();
    ConstructionContext context(
        structure, buffer, byteOffset, byteLength, ConstructionContext::DataView);
    ASSERT(context);
    JSDataView* result =
        new (NotNull, allocateCell<JSDataView>(vm.heap)) JSDataView(vm, context, buffer.get());
    result->finishCreation(vm);
    return result;
}
Example #10
0
PassRefPtr<ArrayBufferView> JSDataView::getTypedArrayImpl(JSArrayBufferView* object)
{
    JSDataView* thisObject = jsCast<JSDataView*>(object);
    return thisObject->typedImpl();
}
Example #11
0
JSValue jsDataViewConstructor(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSDataView* domObject = static_cast<JSDataView*>(asObject(slotBase));
    return JSDataView::getConstructor(exec, domObject->globalObject());
}