/*
 * Copyright (C) 2011-2018 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. AND ITS CONTRIBUTORS ``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 ITS 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.
 */

#pragma once

#include "GCAssertions.h"
#include "HandleTypes.h"
#include "StructureID.h"
#include <type_traits>
#include <wtf/RawPtrTraits.h>
#include <wtf/RawValueTraits.h>

namespace JSC {

namespace DFG {
class DesiredWriteBarrier;
}

class JSCell;
class VM;
class JSGlobalObject;

template<class T>
using WriteBarrierTraitsSelect = typename std::conditional<std::is_same<T, Unknown>::value,
    RawValueTraits<T>, RawPtrTraits<T>
>::type;

template<class T, typename Traits = WriteBarrierTraitsSelect<T>> class WriteBarrierBase;
template<> class WriteBarrierBase<JSValue>;

JS_EXPORT_PRIVATE void slowValidateCell(JSCell*);
JS_EXPORT_PRIVATE void slowValidateCell(JSGlobalObject*);
    
#if ENABLE(GC_VALIDATION)
template<class T> inline void validateCell(T cell)
{
    ASSERT_GC_OBJECT_INHERITS(cell, std::remove_pointer<T>::type::info());
}

template<> inline void validateCell<JSCell*>(JSCell* cell)
{
    slowValidateCell(cell);
}

template<> inline void validateCell<JSGlobalObject*>(JSGlobalObject* globalObject)
{
    slowValidateCell(globalObject);
}
#else
template<class T> inline void validateCell(T)
{
}
#endif

// We have a separate base class with no constructors for use in Unions.
template <typename T, typename Traits> class WriteBarrierBase {
    using StorageType = typename Traits::StorageType;

public:
    void set(VM&, const JSCell* owner, T* value);
    
    // This is meant to be used like operator=, but is called copyFrom instead, in
    // order to kindly inform the C++ compiler that its advice is not appreciated.
    void copyFrom(const WriteBarrierBase& other)
    {
        // FIXME add version with different Traits once needed.
        Traits::exchange(m_cell, other.m_cell);
    }

    void setMayBeNull(VM&, const JSCell* owner, T* value);

    // Should only be used by JSCell during early initialisation
    // when some basic types aren't yet completely instantiated
    void setEarlyValue(VM&, const JSCell* owner, T* value);
    
    T* get() const
    {
        // Copy m_cell to a local to avoid multiple-read issues. (See <http://webkit.org/b/110854>)
        StorageType cell = this->cell();
        if (cell)
            validateCell(reinterpret_cast<JSCell*>(static_cast<void*>(Traits::unwrap(cell))));
        return Traits::unwrap(cell);
    }

    T* operator*() const
    {
        StorageType cell = this->cell();
        ASSERT(cell);
        auto unwrapped = Traits::unwrap(cell);
        validateCell<T>(unwrapped);
        return Traits::unwrap(unwrapped);
    }

    T* operator->() const
    {
        StorageType cell = this->cell();
        ASSERT(cell);
        auto unwrapped = Traits::unwrap(cell);
        validateCell(unwrapped);
        return unwrapped;
    }

    void clear() { Traits::exchange(m_cell, nullptr); }

    // Slot cannot be used when pointers aren't stored as-is.
    template<typename BarrierT, typename BarrierTraits, std::enable_if_t<std::is_same<BarrierTraits, RawPtrTraits<BarrierT>>::value, void*> = nullptr>
    struct SlotHelper {
        static BarrierT** reinterpret(typename BarrierTraits::StorageType* cell) { return reinterpret_cast<T**>(cell); }
    };

    T** slot()
    {
        return SlotHelper<T, Traits>::reinterpret(&m_cell);
    }
    
    explicit operator bool() const { return !!cell(); }
    
    bool operator!() const { return !cell(); }

    void setWithoutWriteBarrier(T* value)
    {
#if ENABLE(WRITE_BARRIER_PROFILING)
        WriteBarrierCounters::usesWithoutBarrierFromCpp.count();
#endif
        Traits::exchange(this->m_cell, value);
    }

    T* unvalidatedGet() const { return Traits::unwrap(cell()); }

private:
    StorageType cell() const { return m_cell; }

    StorageType m_cell;
};

template <> class WriteBarrierBase<Unknown, RawValueTraits<Unknown>> {
public:
    void set(VM&, const JSCell* owner, JSValue);
    void setWithoutWriteBarrier(JSValue value)
    {
        m_value = JSValue::encode(value);
    }

    JSValue get() const
    {
        return JSValue::decode(m_value);
    }
    void clear() { m_value = JSValue::encode(JSValue()); }
    void setUndefined() { m_value = JSValue::encode(jsUndefined()); }
    void setStartingValue(JSValue value) { m_value = JSValue::encode(value); }
    bool isNumber() const { return get().isNumber(); }
    bool isInt32() const { return get().isInt32(); }
    bool isObject() const { return get().isObject(); }
    bool isNull() const { return get().isNull(); }
    bool isGetterSetter() const { return get().isGetterSetter(); }
    bool isCustomGetterSetter() const { return get().isCustomGetterSetter(); }
    
    JSValue* slot() const
    { 
        return bitwise_cast<JSValue*>(&m_value);
    }
    
    int32_t* tagPointer() { return &bitwise_cast<EncodedValueDescriptor*>(&m_value)->asBits.tag; }
    int32_t* payloadPointer() { return &bitwise_cast<EncodedValueDescriptor*>(&m_value)->asBits.payload; }
    
    explicit operator bool() const { return !!get(); }
    bool operator!() const { return !get(); } 
    
private:
    EncodedJSValue m_value;
};

template <typename T, typename Traits = WriteBarrierTraitsSelect<T>>
class WriteBarrier : public WriteBarrierBase<T, Traits> {
    WTF_MAKE_FAST_ALLOCATED;
public:
    WriteBarrier()
    {
        this->setWithoutWriteBarrier(nullptr);
    }

    WriteBarrier(VM& vm, const JSCell* owner, T* value)
    {
        this->set(vm, owner, value);
    }

    WriteBarrier(DFG::DesiredWriteBarrier&, T* value)
    {
        ASSERT(isCompilationThread());
        this->setWithoutWriteBarrier(value);
    }

    enum MayBeNullTag { MayBeNull };
    WriteBarrier(VM& vm, const JSCell* owner, T* value, MayBeNullTag)
    {
        this->setMayBeNull(vm, owner, value);
    }
};

enum UndefinedWriteBarrierTagType { UndefinedWriteBarrierTag };
template <>
class WriteBarrier<Unknown, RawValueTraits<Unknown>> : public WriteBarrierBase<Unknown, RawValueTraits<Unknown>> {
    WTF_MAKE_FAST_ALLOCATED;
public:
    WriteBarrier()
    {
        this->setWithoutWriteBarrier(JSValue());
    }
    WriteBarrier(UndefinedWriteBarrierTagType)
    {
        this->setWithoutWriteBarrier(jsUndefined());
    }

    WriteBarrier(VM& vm, const JSCell* owner, JSValue value)
    {
        this->set(vm, owner, value);
    }

    WriteBarrier(DFG::DesiredWriteBarrier&, JSValue value)
    {
        ASSERT(isCompilationThread());
        this->setWithoutWriteBarrier(value);
    }
};

template <typename U, typename V, typename TraitsU, typename TraitsV>
inline bool operator==(const WriteBarrierBase<U, TraitsU>& lhs, const WriteBarrierBase<V, TraitsV>& rhs)
{
    return lhs.get() == rhs.get();
}

class WriteBarrierStructureID {
public:
    constexpr WriteBarrierStructureID() = default;

    WriteBarrierStructureID(VM& vm, const JSCell* owner, Structure* value)
    {
        set(vm, owner, value);
    }

    WriteBarrierStructureID(DFG::DesiredWriteBarrier&, Structure* value)
    {
        ASSERT(isCompilationThread());
        setWithoutWriteBarrier(value);
    }

    enum MayBeNullTag { MayBeNull };
    WriteBarrierStructureID(VM& vm, const JSCell* owner, Structure* value, MayBeNullTag)
    {
        setMayBeNull(vm, owner, value);
    }

    void set(VM&, const JSCell* owner, Structure* value);

    void setMayBeNull(VM&, const JSCell* owner, Structure* value);

    // Should only be used by JSCell during early initialisation
    // when some basic types aren't yet completely instantiated
    void setEarlyValue(VM&, const JSCell* owner, Structure* value);

    Structure* get() const
    {
        // Copy m_structureID to a local to avoid multiple-read issues. (See <http://webkit.org/b/110854>)
        StructureID structureID = value();
        if (structureID) {
            Structure* structure = structureID.decode();
            validateCell(reinterpret_cast<JSCell*>(structure));
            return structure;
        }
        return nullptr;
    }

    Structure* operator*() const
    {
        StructureID structureID = value();
        ASSERT(structureID);
        Structure* structure = structureID.decode();
        validateCell(reinterpret_cast<JSCell*>(structure));
        return structure;
    }

    Structure* operator->() const
    {
        StructureID structureID = value();
        ASSERT(structureID);
        Structure* structure = structureID.decode();
        validateCell(reinterpret_cast<JSCell*>(structure));
        return structure;
    }

    void clear()
    {
        m_structureID = { };
    }

    explicit operator bool() const
    {
        return !!value();
    }

    bool operator!() const
    {
        return !value();
    }

    void setWithoutWriteBarrier(Structure* value)
    {
#if ENABLE(WRITE_BARRIER_PROFILING)
        WriteBarrierCounters::usesWithoutBarrierFromCpp.count();
#endif
        if (!value) {
            m_structureID = { };
            return;
        }
        m_structureID = StructureID::encode(value);
    }

    Structure* unvalidatedGet() const
    {
        StructureID structureID = value();
        if (structureID)
            return structureID.decode();
        return nullptr;
    }

    StructureID value() const { return m_structureID; }

private:
    StructureID m_structureID;
};

} // namespace JSC
