/*
 * Copyright (C) 2013-2019 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#include "config.h"
#include "JSDataViewPrototype.h"

#include "Error.h"
#include "JSArrayBuffer.h"
#include "JSDataView.h"
#include "Lookup.h"
#include "JSCInlines.h"
#include "ToNativeFromValue.h"
#include "TypedArrayAdaptors.h"
#include <wtf/FlipBytes.h>

namespace JSC {

/* Source for JSDataViewPrototype.lut.h
@begin dataViewTable
  getInt8               dataViewProtoFuncGetInt8             DontEnum|Function       1  DataViewGetInt8
  getUint8              dataViewProtoFuncGetUint8            DontEnum|Function       1  DataViewGetUint8
  getInt16              dataViewProtoFuncGetInt16            DontEnum|Function       1  DataViewGetInt16
  getUint16             dataViewProtoFuncGetUint16           DontEnum|Function       1  DataViewGetUint16
  getInt32              dataViewProtoFuncGetInt32            DontEnum|Function       1  DataViewGetInt32
  getUint32             dataViewProtoFuncGetUint32           DontEnum|Function       1  DataViewGetUint32
  getFloat32            dataViewProtoFuncGetFloat32          DontEnum|Function       1  DataViewGetFloat32
  getFloat64            dataViewProtoFuncGetFloat64          DontEnum|Function       1  DataViewGetFloat64
  setInt8               dataViewProtoFuncSetInt8             DontEnum|Function       2  DataViewSetInt8
  setUint8              dataViewProtoFuncSetUint8            DontEnum|Function       2  DataViewSetUint8
  setInt16              dataViewProtoFuncSetInt16            DontEnum|Function       2  DataViewSetInt16
  setUint16             dataViewProtoFuncSetUint16           DontEnum|Function       2  DataViewSetUint16
  setInt32              dataViewProtoFuncSetInt32            DontEnum|Function       2  DataViewSetInt32
  setUint32             dataViewProtoFuncSetUint32           DontEnum|Function       2  DataViewSetUint32
  setFloat32            dataViewProtoFuncSetFloat32          DontEnum|Function       2  DataViewSetFloat32
  setFloat64            dataViewProtoFuncSetFloat64          DontEnum|Function       2  DataViewSetFloat64
  buffer                dataViewProtoGetterBuffer            DontEnum|Accessor       0
  byteLength            dataViewProtoGetterByteLength        DontEnum|Accessor       0
  byteOffset            dataViewProtoGetterByteOffset        DontEnum|Accessor       0
@end
*/

EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetInt8(ExecState*);
EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetInt16(ExecState*);
EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetInt32(ExecState*);
EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetUint8(ExecState*);
EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetUint16(ExecState*);
EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetUint32(ExecState*);
EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetFloat32(ExecState*);
EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetFloat64(ExecState*);
EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetInt8(ExecState*);
EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetInt16(ExecState*);
EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetInt32(ExecState*);
EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetUint8(ExecState*);
EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetUint16(ExecState*);
EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetUint32(ExecState*);
EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetFloat32(ExecState*);
EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetFloat64(ExecState*);
EncodedJSValue JSC_HOST_CALL dataViewProtoGetterBuffer(ExecState*);
EncodedJSValue JSC_HOST_CALL dataViewProtoGetterByteLength(ExecState*);
EncodedJSValue JSC_HOST_CALL dataViewProtoGetterByteOffset(ExecState*);

}

#include "JSDataViewPrototype.lut.h"

namespace JSC {

const ClassInfo JSDataViewPrototype::s_info = {
    "DataViewPrototype", &Base::s_info, &dataViewTable, nullptr,
    CREATE_METHOD_TABLE(JSDataViewPrototype)
};

JSDataViewPrototype::JSDataViewPrototype(VM& vm, Structure* structure)
    : Base(vm, structure)
{
}

JSDataViewPrototype* JSDataViewPrototype::create(VM& vm, Structure* structure)
{
    JSDataViewPrototype* prototype =
        new (NotNull, allocateCell<JSDataViewPrototype>(vm.heap))
        JSDataViewPrototype(vm, structure);
    prototype->finishCreation(vm);
    return prototype;
}

void JSDataViewPrototype::finishCreation(JSC::VM& vm)
{
    Base::finishCreation(vm);
    putDirectWithoutTransition(vm, vm.propertyNames->toStringTagSymbol, jsString(vm, "DataView"), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
}

Structure* JSDataViewPrototype::createStructure(
    VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
    return Structure::create(
        vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
}

template<typename Adaptor>
EncodedJSValue getData(ExecState* exec)
{
    VM& vm = exec->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    JSDataView* dataView = jsDynamicCast<JSDataView*>(vm, exec->thisValue());
    if (!dataView)
        return throwVMTypeError(exec, scope, "Receiver of DataView method must be a DataView"_s);
    
    unsigned byteOffset = exec->argument(0).toIndex(exec, "byteOffset");
    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    
    bool littleEndian = false;
    unsigned elementSize = sizeof(typename Adaptor::Type);
    if (elementSize > 1 && exec->argumentCount() >= 2) {
        littleEndian = exec->uncheckedArgument(1).toBoolean(exec);
        RETURN_IF_EXCEPTION(scope, encodedJSValue());
    }
    
    unsigned byteLength = dataView->length();
    if (elementSize > byteLength || byteOffset > byteLength - elementSize)
        return throwVMError(exec, scope, createRangeError(exec, "Out of bounds access"_s));

    const unsigned dataSize = sizeof(typename Adaptor::Type);
    union {
        typename Adaptor::Type value;
        uint8_t rawBytes[dataSize];
    } u = { };

    uint8_t* dataPtr = static_cast<uint8_t*>(dataView->vector()) + byteOffset;

    if (needToFlipBytesIfLittleEndian(littleEndian)) {
        for (unsigned i = dataSize; i--;)
            u.rawBytes[i] = *dataPtr++;
    } else {
        for (unsigned i = 0; i < dataSize; i++)
            u.rawBytes[i] = *dataPtr++;
    }

    return JSValue::encode(Adaptor::toJSValue(u.value));
}

template<typename Adaptor>
EncodedJSValue setData(ExecState* exec)
{
    VM& vm = exec->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    JSDataView* dataView = jsDynamicCast<JSDataView*>(vm, exec->thisValue());
    if (!dataView)
        return throwVMTypeError(exec, scope, "Receiver of DataView method must be a DataView"_s);
    
    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, "Out of bounds access"_s));

    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());
}

IGNORE_CLANG_WARNINGS_BEGIN("missing-prototypes")

EncodedJSValue JSC_HOST_CALL dataViewProtoGetterBuffer(ExecState* exec)
{
    VM& vm = exec->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

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

    return JSValue::encode(view->possiblySharedJSBuffer(exec));
}

EncodedJSValue JSC_HOST_CALL dataViewProtoGetterByteLength(ExecState* exec)
{
    VM& vm = exec->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

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

    return JSValue::encode(jsNumber(view->length()));
}

EncodedJSValue JSC_HOST_CALL dataViewProtoGetterByteOffset(ExecState* exec)
{
    VM& vm = exec->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

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

    return JSValue::encode(jsNumber(view->byteOffset()));
}

EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetInt8(ExecState* exec)
{
    return getData<Int8Adaptor>(exec);
}

EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetInt16(ExecState* exec)
{
    return getData<Int16Adaptor>(exec);
}

EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetInt32(ExecState* exec)
{
    return getData<Int32Adaptor>(exec);
}

EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetUint8(ExecState* exec)
{
    return getData<Uint8Adaptor>(exec);
}

EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetUint16(ExecState* exec)
{
    return getData<Uint16Adaptor>(exec);
}

EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetUint32(ExecState* exec)
{
    return getData<Uint32Adaptor>(exec);
}

EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetFloat32(ExecState* exec)
{
    return getData<Float32Adaptor>(exec);
}

EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetFloat64(ExecState* exec)
{
    return getData<Float64Adaptor>(exec);
}

EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetInt8(ExecState* exec)
{
    return setData<Int8Adaptor>(exec);
}

EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetInt16(ExecState* exec)
{
    return setData<Int16Adaptor>(exec);
}

EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetInt32(ExecState* exec)
{
    return setData<Int32Adaptor>(exec);
}

EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetUint8(ExecState* exec)
{
    return setData<Uint8Adaptor>(exec);
}

EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetUint16(ExecState* exec)
{
    return setData<Uint16Adaptor>(exec);
}

EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetUint32(ExecState* exec)
{
    return setData<Uint32Adaptor>(exec);
}

EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetFloat32(ExecState* exec)
{
    return setData<Float32Adaptor>(exec);
}

EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetFloat64(ExecState* exec)
{
    return setData<Float64Adaptor>(exec);
}
IGNORE_CLANG_WARNINGS_END

} // namespace JSC
