/*
 * Copyright (C) 2016-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 "AtomicsObject.h"

#include "FrameTracers.h"
#include "JSCInlines.h"
#include "JSTypedArrays.h"
#include "ObjectPrototype.h"
#include "ReleaseHeapAccessScope.h"
#include "TypedArrayController.h"

namespace JSC {

STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(AtomicsObject);

#define FOR_EACH_ATOMICS_FUNC(macro)                                    \
    macro(add, Add, 3)                                                  \
    macro(and, And, 3)                                                  \
    macro(compareExchange, CompareExchange, 4)                          \
    macro(exchange, Exchange, 3)                                        \
    macro(isLockFree, IsLockFree, 1)                                    \
    macro(load, Load, 2)                                                \
    macro(or, Or, 3)                                                    \
    macro(store, Store, 3)                                              \
    macro(sub, Sub, 3)                                                  \
    macro(wait, Wait, 4)                                                \
    macro(wake, Wake, 3)                                                \
    macro(xor, Xor, 3)

#define DECLARE_FUNC_PROTO(lowerName, upperName, count)                 \
    EncodedJSValue JSC_HOST_CALL atomicsFunc ## upperName(ExecState*);
FOR_EACH_ATOMICS_FUNC(DECLARE_FUNC_PROTO)
#undef DECLARE_FUNC_PROTO

const ClassInfo AtomicsObject::s_info = { "Atomics", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(AtomicsObject) };

AtomicsObject::AtomicsObject(VM& vm, Structure* structure)
    : JSNonFinalObject(vm, structure)
{
}

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

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

void AtomicsObject::finishCreation(VM& vm, JSGlobalObject* globalObject)
{
    Base::finishCreation(vm);
    ASSERT(inherits(vm, info()));
    
#define PUT_DIRECT_NATIVE_FUNC(lowerName, upperName, count) \
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, #lowerName), count, atomicsFunc ## upperName, Atomics ## upperName ## Intrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
    FOR_EACH_ATOMICS_FUNC(PUT_DIRECT_NATIVE_FUNC)
#undef PUT_DIRECT_NATIVE_FUNC
}

namespace {

template<typename Adaptor, typename Func>
EncodedJSValue atomicOperationWithArgsCase(ExecState* exec, const JSValue* args, ThrowScope& scope, JSArrayBufferView* typedArrayView, unsigned accessIndex, const Func& func)
{
    JSGenericTypedArrayView<Adaptor>* typedArray = jsCast<JSGenericTypedArrayView<Adaptor>*>(typedArrayView);
    
    double extraArgs[Func::numExtraArgs + 1]; // Add 1 to avoid 0 size array error in VS.
    for (unsigned i = 0; i < Func::numExtraArgs; ++i) {
        double value = args[2 + i].toInteger(exec);
        RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined()));
        extraArgs[i] = value;
    }

    return JSValue::encode(func(typedArray->typedVector() + accessIndex, extraArgs));
}

unsigned validatedAccessIndex(VM& vm, ExecState* exec, JSValue accessIndexValue, JSArrayBufferView* typedArrayView)
{
    auto scope = DECLARE_THROW_SCOPE(vm);
    if (UNLIKELY(!accessIndexValue.isInt32())) {
        double accessIndexDouble = accessIndexValue.toNumber(exec);
        RETURN_IF_EXCEPTION(scope, 0);
        if (accessIndexDouble == 0)
            accessIndexValue = jsNumber(0);
        else {
            accessIndexValue = jsNumber(accessIndexDouble);
            if (!accessIndexValue.isInt32()) {
                throwRangeError(exec, scope, "Access index is not an integer."_s);
                return 0;
            }
        }
    }
    int32_t accessIndex = accessIndexValue.asInt32();
    
    ASSERT(typedArrayView->length() <= static_cast<unsigned>(INT_MAX));
    if (static_cast<unsigned>(accessIndex) >= typedArrayView->length()) {
        throwRangeError(exec, scope, "Access index out of bounds for atomic access."_s);
        return 0;
    }
    
    return accessIndex;
}

template<typename Func>
EncodedJSValue atomicOperationWithArgs(VM& vm, ExecState* exec, const JSValue* args, const Func& func)
{
    auto scope = DECLARE_THROW_SCOPE(vm);

    JSValue typedArrayValue = args[0];
    if (!typedArrayValue.isCell()) {
        throwTypeError(exec, scope, "Typed array argument must be a cell."_s);
        return JSValue::encode(jsUndefined());
    }
    
    JSCell* typedArrayCell = typedArrayValue.asCell();
    
    JSType type = typedArrayCell->type();
    switch (type) {
    case Int8ArrayType:
    case Int16ArrayType:
    case Int32ArrayType:
    case Uint8ArrayType:
    case Uint16ArrayType:
    case Uint32ArrayType:
        break;
    default:
        throwTypeError(exec, scope, "Typed array argument must be an Int8Array, Int16Array, Int32Array, Uint8Array, Uint16Array, or Uint32Array."_s);
        return JSValue::encode(jsUndefined());
    }
    
    JSArrayBufferView* typedArrayView = jsCast<JSArrayBufferView*>(typedArrayCell);
    if (!typedArrayView->isShared()) {
        throwTypeError(exec, scope, "Typed array argument must wrap a SharedArrayBuffer."_s);
        return JSValue::encode(jsUndefined());
    }
    
    unsigned accessIndex = validatedAccessIndex(vm, exec, args[1], typedArrayView);
    RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined()));
    
    switch (type) {
    case Int8ArrayType:
        return atomicOperationWithArgsCase<Int8Adaptor>(exec, args, scope, typedArrayView, accessIndex, func);
    case Int16ArrayType:
        return atomicOperationWithArgsCase<Int16Adaptor>(exec, args, scope, typedArrayView, accessIndex, func);
    case Int32ArrayType:
        return atomicOperationWithArgsCase<Int32Adaptor>(exec, args, scope, typedArrayView, accessIndex, func);
    case Uint8ArrayType:
        return atomicOperationWithArgsCase<Uint8Adaptor>(exec, args, scope, typedArrayView, accessIndex, func);
    case Uint16ArrayType:
        return atomicOperationWithArgsCase<Uint16Adaptor>(exec, args, scope, typedArrayView, accessIndex, func);
    case Uint32ArrayType:
        return atomicOperationWithArgsCase<Uint32Adaptor>(exec, args, scope, typedArrayView, accessIndex, func);
    default:
        RELEASE_ASSERT_NOT_REACHED();
        return JSValue::encode(jsUndefined());
    }
}

template<typename Func>
EncodedJSValue atomicOperationWithArgs(ExecState* exec, const Func& func)
{
    JSValue args[2 + Func::numExtraArgs];
    for (unsigned i = 2 + Func::numExtraArgs; i--;)
        args[i] = exec->argument(i);
    return atomicOperationWithArgs(exec->vm(), exec, args, func);
}

struct AddFunc {
    static constexpr unsigned numExtraArgs = 1;
    
    template<typename T>
    JSValue operator()(T* ptr, const double* args) const
    {
        return jsNumber(WTF::atomicExchangeAdd(ptr, toInt32(args[0])));
    }
};

struct AndFunc {
    static constexpr unsigned numExtraArgs = 1;
    
    template<typename T>
    JSValue operator()(T* ptr, const double* args) const
    {
        return jsNumber(WTF::atomicExchangeAnd(ptr, toInt32(args[0])));
    }
};

struct CompareExchangeFunc {
    static constexpr unsigned numExtraArgs = 2;
    
    template<typename T>
    JSValue operator()(T* ptr, const double* args) const
    {
        T expected = static_cast<T>(toInt32(args[0]));
        T newValue = static_cast<T>(toInt32(args[1]));
        return jsNumber(WTF::atomicCompareExchangeStrong(ptr, expected, newValue));
    }
};

struct ExchangeFunc {
    static constexpr unsigned numExtraArgs = 1;
    
    template<typename T>
    JSValue operator()(T* ptr, const double* args) const
    {
        return jsNumber(WTF::atomicExchange(ptr, static_cast<T>(toInt32(args[0]))));
    }
};

struct LoadFunc {
    static constexpr unsigned numExtraArgs = 0;
    
    template<typename T>
    JSValue operator()(T* ptr, const double*) const
    {
        return jsNumber(WTF::atomicLoadFullyFenced(ptr));
    }
};

struct OrFunc {
    static constexpr unsigned numExtraArgs = 1;
    
    template<typename T>
    JSValue operator()(T* ptr, const double* args) const
    {
        return jsNumber(WTF::atomicExchangeOr(ptr, toInt32(args[0])));
    }
};

struct StoreFunc {
    static constexpr unsigned numExtraArgs = 1;
    
    template<typename T>
    JSValue operator()(T* ptr, const double* args) const
    {
        double valueAsInt = args[0];
        T valueAsT = static_cast<T>(toInt32(valueAsInt));
        WTF::atomicStoreFullyFenced(ptr, valueAsT);
        return jsNumber(valueAsInt);
    }
};

struct SubFunc {
    static constexpr unsigned numExtraArgs = 1;
    
    template<typename T>
    JSValue operator()(T* ptr, const double* args) const
    {
        return jsNumber(WTF::atomicExchangeSub(ptr, toInt32(args[0])));
    }
};

struct XorFunc {
    static constexpr unsigned numExtraArgs = 1;
    
    template<typename T>
    JSValue operator()(T* ptr, const double* args) const
    {
        return jsNumber(WTF::atomicExchangeXor(ptr, toInt32(args[0])));
    }
};

EncodedJSValue isLockFree(ExecState* exec, JSValue arg)
{
    VM& vm = exec->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    int32_t size = arg.toInt32(exec);
    RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined()));
    
    bool result;
    switch (size) {
    case 1:
    case 2:
    case 4:
        result = true;
        break;
    default:
        result = false;
        break;
    }
    return JSValue::encode(jsBoolean(result));
}

} // anonymous namespace

EncodedJSValue JSC_HOST_CALL atomicsFuncAdd(ExecState* exec)
{
    return atomicOperationWithArgs(exec, AddFunc());
}

EncodedJSValue JSC_HOST_CALL atomicsFuncAnd(ExecState* exec)
{
    return atomicOperationWithArgs(exec, AndFunc());
}

EncodedJSValue JSC_HOST_CALL atomicsFuncCompareExchange(ExecState* exec)
{
    return atomicOperationWithArgs(exec, CompareExchangeFunc());
}

EncodedJSValue JSC_HOST_CALL atomicsFuncExchange(ExecState* exec)
{
    return atomicOperationWithArgs(exec, ExchangeFunc());
}

EncodedJSValue JSC_HOST_CALL atomicsFuncIsLockFree(ExecState* exec)
{
    return isLockFree(exec, exec->argument(0));
}

EncodedJSValue JSC_HOST_CALL atomicsFuncLoad(ExecState* exec)
{
    return atomicOperationWithArgs(exec, LoadFunc());
}

EncodedJSValue JSC_HOST_CALL atomicsFuncOr(ExecState* exec)
{
    return atomicOperationWithArgs(exec, OrFunc());
}

EncodedJSValue JSC_HOST_CALL atomicsFuncStore(ExecState* exec)
{
    return atomicOperationWithArgs(exec, StoreFunc());
}

EncodedJSValue JSC_HOST_CALL atomicsFuncSub(ExecState* exec)
{
    return atomicOperationWithArgs(exec, SubFunc());
}

EncodedJSValue JSC_HOST_CALL atomicsFuncWait(ExecState* exec)
{
    VM& vm = exec->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);
    
    JSInt32Array* typedArray = jsDynamicCast<JSInt32Array*>(vm, exec->argument(0));
    if (!typedArray) {
        throwTypeError(exec, scope, "Typed array for wait/wake must be an Int32Array."_s);
        return JSValue::encode(jsUndefined());
    }
    
    if (!typedArray->isShared()) {
        throwTypeError(exec, scope, "Typed array for wait/wake must wrap a SharedArrayBuffer."_s);
        return JSValue::encode(jsUndefined());
    }

    unsigned accessIndex = validatedAccessIndex(vm, exec, exec->argument(1), typedArray);
    RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined()));
    
    int32_t* ptr = typedArray->typedVector() + accessIndex;
    
    int32_t expectedValue = exec->argument(2).toInt32(exec);
    RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined()));
    
    double timeoutInMilliseconds = exec->argument(3).toNumber(exec);
    RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined()));
    
    if (!vm.m_typedArrayController->isAtomicsWaitAllowedOnCurrentThread()) {
        throwTypeError(exec, scope, "Atomics.wait cannot be called from the current thread."_s);
        return JSValue::encode(jsUndefined());
    }
    
    Seconds timeout = Seconds::fromMilliseconds(timeoutInMilliseconds);

    // This covers the proposed rule:
    //
    // 4. If timeout is not provided or is undefined then let t be +inf. Otherwise:
    //     a. Let q be ? ToNumber(timeout).
    //     b. If q is NaN then let t be +inf, otherwise let t be max(0, q).
    //
    // exec->argument(3) returns undefined if it's not provided and ToNumber(undefined) returns NaN,
    // so NaN is the only special case.
    if (!std::isnan(timeout))
        timeout = std::max(0_s, timeout);
    else
        timeout = Seconds::infinity();
    
    bool didPassValidation = false;
    ParkingLot::ParkResult result;
    {
        ReleaseHeapAccessScope releaseHeapAccessScope(vm.heap);
        result = ParkingLot::parkConditionally(
            ptr,
            [&] () -> bool {
                didPassValidation = WTF::atomicLoad(ptr) == expectedValue;
                return didPassValidation;
            },
            [] () { },
            MonotonicTime::now() + timeout);
    }
    const char* resultString;
    if (!didPassValidation)
        resultString = "not-equal";
    else if (!result.wasUnparked)
        resultString = "timed-out";
    else
        resultString = "ok";
    return JSValue::encode(jsString(vm, resultString));
}

EncodedJSValue JSC_HOST_CALL atomicsFuncWake(ExecState* exec)
{
    VM& vm = exec->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);
    
    JSInt32Array* typedArray = jsDynamicCast<JSInt32Array*>(vm, exec->argument(0));
    if (!typedArray) {
        throwTypeError(exec, scope, "Typed array for wait/wake must be an Int32Array."_s);
        return JSValue::encode(jsUndefined());
    }
    
    if (!typedArray->isShared()) {
        throwTypeError(exec, scope, "Typed array for wait/wake must wrap a SharedArrayBuffer."_s);
        return JSValue::encode(jsUndefined());
    }

    unsigned accessIndex = validatedAccessIndex(vm, exec, exec->argument(1), typedArray);
    RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined()));
    
    int32_t* ptr = typedArray->typedVector() + accessIndex;
    
    JSValue countValue = exec->argument(2);
    unsigned count = UINT_MAX;
    if (!countValue.isUndefined()) {
        int32_t countInt = countValue.toInt32(exec);
        RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined()));
        count = std::max(0, countInt);
    }

    return JSValue::encode(jsNumber(ParkingLot::unparkCount(ptr, count)));
}

EncodedJSValue JSC_HOST_CALL atomicsFuncXor(ExecState* exec)
{
    return atomicOperationWithArgs(exec, XorFunc());
}

EncodedJSValue JIT_OPERATION operationAtomicsAdd(ExecState* exec, EncodedJSValue base, EncodedJSValue index, EncodedJSValue operand)
{
    VM& vm = exec->vm();
    NativeCallFrameTracer tracer(vm, exec);
    JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)};
    return atomicOperationWithArgs(vm, exec, args, AddFunc());
}

EncodedJSValue JIT_OPERATION operationAtomicsAnd(ExecState* exec, EncodedJSValue base, EncodedJSValue index, EncodedJSValue operand)
{
    VM& vm = exec->vm();
    NativeCallFrameTracer tracer(vm, exec);
    JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)};
    return atomicOperationWithArgs(vm, exec, args, AndFunc());
}

EncodedJSValue JIT_OPERATION operationAtomicsCompareExchange(ExecState* exec, EncodedJSValue base, EncodedJSValue index, EncodedJSValue expected, EncodedJSValue newValue)
{
    VM& vm = exec->vm();
    NativeCallFrameTracer tracer(vm, exec);
    JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(expected), JSValue::decode(newValue)};
    return atomicOperationWithArgs(vm, exec, args, CompareExchangeFunc());
}

EncodedJSValue JIT_OPERATION operationAtomicsExchange(ExecState* exec, EncodedJSValue base, EncodedJSValue index, EncodedJSValue operand)
{
    VM& vm = exec->vm();
    NativeCallFrameTracer tracer(vm, exec);
    JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)};
    return atomicOperationWithArgs(vm, exec, args, ExchangeFunc());
}

EncodedJSValue JIT_OPERATION operationAtomicsIsLockFree(ExecState* exec, EncodedJSValue size)
{
    VM& vm = exec->vm();
    NativeCallFrameTracer tracer(vm, exec);
    return isLockFree(exec, JSValue::decode(size));
}

EncodedJSValue JIT_OPERATION operationAtomicsLoad(ExecState* exec, EncodedJSValue base, EncodedJSValue index)
{
    VM& vm = exec->vm();
    NativeCallFrameTracer tracer(vm, exec);
    JSValue args[] = {JSValue::decode(base), JSValue::decode(index)};
    return atomicOperationWithArgs(vm, exec, args, LoadFunc());
}

EncodedJSValue JIT_OPERATION operationAtomicsOr(ExecState* exec, EncodedJSValue base, EncodedJSValue index, EncodedJSValue operand)
{
    VM& vm = exec->vm();
    NativeCallFrameTracer tracer(vm, exec);
    JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)};
    return atomicOperationWithArgs(vm, exec, args, OrFunc());
}

EncodedJSValue JIT_OPERATION operationAtomicsStore(ExecState* exec, EncodedJSValue base, EncodedJSValue index, EncodedJSValue operand)
{
    VM& vm = exec->vm();
    NativeCallFrameTracer tracer(vm, exec);
    JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)};
    return atomicOperationWithArgs(vm, exec, args, StoreFunc());
}

EncodedJSValue JIT_OPERATION operationAtomicsSub(ExecState* exec, EncodedJSValue base, EncodedJSValue index, EncodedJSValue operand)
{
    VM& vm = exec->vm();
    NativeCallFrameTracer tracer(vm, exec);
    JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)};
    return atomicOperationWithArgs(vm, exec, args, SubFunc());
}

EncodedJSValue JIT_OPERATION operationAtomicsXor(ExecState* exec, EncodedJSValue base, EncodedJSValue index, EncodedJSValue operand)
{
    VM& vm = exec->vm();
    NativeCallFrameTracer tracer(vm, exec);
    JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)};
    return atomicOperationWithArgs(vm, exec, args, XorFunc());
}

} // namespace JSC

