/*
 * Copyright (C) 2011-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. 
 */

#pragma once

#include "CallFrame.h"
#include "VirtualRegister.h"

#include <wtf/PrintStream.h>
#include <wtf/Vector.h>

namespace JSC {

template<typename T> struct OperandValueTraits;

constexpr unsigned maxNumCheckpointTmps = 4;

// A OperandKind::Tmp is one that exists for exiting to a checkpoint but does not exist between bytecodes.
enum class OperandKind : uint32_t { Argument, Local, Tmp }; // Keep bit-width in sync with Operand::operandKindBits' definition.
static constexpr OperandKind lastOperandKind = OperandKind::Tmp;

class Operand {
public:
    static constexpr unsigned kindBits = WTF::getMSBSetConstexpr(static_cast<std::underlying_type_t<OperandKind>>(lastOperandKind)) + 1;
    static constexpr unsigned maxBits = 32 + kindBits;
    static_assert(maxBits == 34);

    Operand() = default;
    Operand(const Operand&) = default;

    Operand(VirtualRegister operand)
        : Operand(operand.isLocal() ? OperandKind::Local : OperandKind::Argument, operand.offset())
    { }

    Operand(OperandKind kind, int operand)
#if CPU(LITTLE_ENDIAN)
        : m_operand(operand)
        , m_kind(kind)
#else
        : m_kind(kind)
        , m_operand(operand)
#endif
    { 
        ASSERT(kind == OperandKind::Tmp || VirtualRegister(operand).isLocal() == (kind == OperandKind::Local));
    }
    static Operand tmp(uint32_t index) { return Operand(OperandKind::Tmp, index); }

    OperandKind kind() const { return m_kind; }
    int value() const { return m_operand; }
    VirtualRegister virtualRegister() const
    {
        ASSERT(m_kind != OperandKind::Tmp);
        return VirtualRegister(m_operand);
    }
    uint64_t asBits() const
    {
        uint64_t bits = bitwise_cast<uint64_t>(*this);
        ASSERT(bits < (1ULL << maxBits));
        return bits;
    }
    static Operand fromBits(uint64_t value);

    bool isTmp() const { return kind() == OperandKind::Tmp; }
    bool isArgument() const { return kind() == OperandKind::Argument; }
    bool isLocal() const { return kind() == OperandKind::Local && virtualRegister().isLocal(); }
    bool isHeader() const { return kind() != OperandKind::Tmp && virtualRegister().isHeader(); }
    bool isConstant() const { return kind() != OperandKind::Tmp && virtualRegister().isConstant(); }

    int toArgument() const { ASSERT(isArgument()); return virtualRegister().toArgument(); }
    int toLocal() const { ASSERT(isLocal()); return virtualRegister().toLocal(); }

    inline bool isValid() const;

    inline bool operator==(const Operand&) const;

    void dump(PrintStream&) const;

private:
#if CPU(LITTLE_ENDIAN)
    int m_operand { VirtualRegister::invalidVirtualRegister };
    OperandKind m_kind { OperandKind::Argument };
#else
    OperandKind m_kind { OperandKind::Argument };
    int m_operand { VirtualRegister::invalidVirtualRegister };
#endif
};

ALWAYS_INLINE bool Operand::operator==(const Operand& other) const
{
    if (kind() != other.kind())
        return false;
    if (isTmp())
        return value() == other.value();
    return virtualRegister() == other.virtualRegister();
}

inline bool Operand::isValid() const
{
    if (isTmp())
        return value() >= 0;
    return virtualRegister().isValid();
}

inline Operand Operand::fromBits(uint64_t value)
{
    Operand result = bitwise_cast<Operand>(value);
    ASSERT(result.isValid());
    return result;
}

static_assert(sizeof(Operand) == sizeof(uint64_t), "Operand::asBits() relies on this.");

enum OperandsLikeTag { OperandsLike };

template<typename T>
class Operands {
public:
    using Storage = std::conditional_t<std::is_same_v<T, bool>, FastBitVector, Vector<T, 0, UnsafeVectorOverflow>>;
    using RefType = std::conditional_t<std::is_same_v<T, bool>, FastBitReference, T&>;
    using ConstRefType = std::conditional_t<std::is_same_v<T, bool>, bool, const T&>;

    Operands() = default;

    explicit Operands(size_t numArguments, size_t numLocals, size_t numTmps)
        : m_numArguments(numArguments)
        , m_numLocals(numLocals)
    {
        size_t size = numArguments + numLocals + numTmps;
        m_values.grow(size);
        if (!WTF::VectorTraits<T>::needsInitialization)
            m_values.fill(T());
    }

    explicit Operands(size_t numArguments, size_t numLocals, size_t numTmps, const T& initialValue)
        : m_numArguments(numArguments)
        , m_numLocals(numLocals)
    {
        m_values.grow(numArguments + numLocals + numTmps);
        m_values.fill(initialValue);
    }
    
    template<typename U>
    explicit Operands(OperandsLikeTag, const Operands<U>& other, const T& initialValue = T())
        : m_numArguments(other.numberOfArguments())
        , m_numLocals(other.numberOfLocals())
    {
        m_values.grow(other.size());
        m_values.fill(initialValue);
    }

    size_t numberOfArguments() const { return m_numArguments; }
    size_t numberOfLocals() const { return m_numLocals; }
    size_t numberOfTmps() const { return m_values.size() - numberOfArguments() - numberOfLocals(); }

    size_t tmpIndex(size_t idx) const
    {
        ASSERT(idx < numberOfTmps());
        return idx + numberOfArguments() + numberOfLocals();
    }
    size_t argumentIndex(size_t idx) const
    {
        ASSERT(idx < numberOfArguments());
        return idx;
    }
    
    size_t localIndex(size_t idx) const
    {
        ASSERT(idx < numberOfLocals());
        return numberOfArguments() + idx;
    }

    RefType tmp(size_t idx) { return m_values[tmpIndex(idx)]; }
    ConstRefType tmp(size_t idx) const { return m_values[tmpIndex(idx)]; }
    
    RefType argument(size_t idx) { return m_values[argumentIndex(idx)]; }
    ConstRefType argument(size_t idx) const { return m_values[argumentIndex(idx)]; }
    
    RefType local(size_t idx) { return m_values[localIndex(idx)]; }
    ConstRefType local(size_t idx) const { return m_values[localIndex(idx)]; }
    
    template<OperandKind operandKind>
    size_t sizeFor() const
    {
        switch (operandKind) {
        case OperandKind::Tmp:
            return numberOfTmps();
        case OperandKind::Argument:
            return numberOfArguments();
        case OperandKind::Local:
            return numberOfLocals();
        }
        RELEASE_ASSERT_NOT_REACHED();
        return 0;
    }
    template<OperandKind operandKind>
    RefType atFor(size_t idx)
    {
        switch (operandKind) {
        case OperandKind::Tmp:
            return tmp(idx);
        case OperandKind::Argument:
            return argument(idx);
        case OperandKind::Local:
            return local(idx);
        }
        RELEASE_ASSERT_NOT_REACHED();
        return tmp(0);
    }
    template<OperandKind operandKind>
    ConstRefType atFor(size_t idx) const
    {
        switch (operandKind) {
        case OperandKind::Tmp:
            return tmp(idx);
        case OperandKind::Argument:
            return argument(idx);
        case OperandKind::Local:
            return local(idx);
        }
        RELEASE_ASSERT_NOT_REACHED();
        return tmp(0);
    }

    void ensureLocals(size_t size, const T& ensuredValue = T())
    {
        if (size <= numberOfLocals())
            return;

        size_t newSize = numberOfArguments() + numberOfTmps() + size;
        size_t oldNumLocals = numberOfLocals();
        size_t oldNumTmps = numberOfTmps();
        m_values.grow(newSize);
        for (size_t i = 0; i < oldNumTmps; ++i)
            m_values[newSize - 1 - i] = m_values[tmpIndex(oldNumTmps - 1 - i)];

        m_numLocals = size;
        if (ensuredValue != T() || !WTF::VectorTraits<T>::needsInitialization) {
            for (size_t i = 0; i < size - oldNumLocals; ++i)
                m_values[localIndex(oldNumLocals + i)] = ensuredValue;
        }
    }

    void ensureTmps(size_t size, const T& ensuredValue = T())
    {
        if (size <= numberOfTmps())
            return;

        size_t oldSize = m_values.size();
        size_t newSize = numberOfArguments() + numberOfLocals() + size;
        m_values.grow(newSize);

        if (ensuredValue != T() || !WTF::VectorTraits<T>::needsInitialization) {
            for (size_t i = oldSize; i < newSize; ++i)
                m_values[i] = ensuredValue;
        }
    }
    
    void setLocal(size_t idx, const T& value)
    {
        ensureLocals(idx + 1);
        local(idx) = value;
    }
    
    T getLocal(size_t idx)
    {
        return idx >= numberOfLocals() ? T() : local(idx);
    }
    
    void setArgumentFirstTime(size_t idx, const T& value)
    {
        ASSERT(m_values[idx] == T());
        argument(idx) = value;
    }
    
    void setLocalFirstTime(size_t idx, const T& value)
    {
        ASSERT(idx >= numberOfLocals() || local(idx) == T());
        setLocal(idx, value);
    }

    RefType getForOperandIndex(size_t index) { return m_values[index]; }
    ConstRefType getForOperandIndex(size_t index) const { return const_cast<Operands*>(this)->getForOperandIndex(index); }

    size_t operandIndex(VirtualRegister operand) const
    {
        if (operand.isArgument())
            return argumentIndex(operand.toArgument());
        return localIndex(operand.toLocal());
    }
    
    size_t operandIndex(Operand op) const
    {
        if (!op.isTmp())
            return operandIndex(op.virtualRegister());
        return tmpIndex(op.value());
    }
    
    RefType operand(VirtualRegister operand)
    {
        if (operand.isArgument())
            return argument(operand.toArgument());
        return local(operand.toLocal());
    }

    RefType operand(Operand op)
    {
        if (!op.isTmp())
            return operand(op.virtualRegister());
        return tmp(op.value());
    }

    ConstRefType operand(VirtualRegister operand) const { return const_cast<Operands*>(this)->operand(operand); }
    ConstRefType operand(Operand operand) const { return const_cast<Operands*>(this)->operand(operand); }
    
    bool hasOperand(VirtualRegister operand) const
    {
        if (operand.isArgument())
            return true;
        return static_cast<size_t>(operand.toLocal()) < numberOfLocals();
    }
    bool hasOperand(Operand op) const
    {
        if (op.isTmp()) {
            ASSERT(op.value() >= 0);
            return static_cast<size_t>(op.value()) < numberOfTmps();
        }
        return hasOperand(op.virtualRegister());
    }
    
    void setOperand(Operand operand, const T& value)
    {
        this->operand(operand) = value;
    }

    size_t size() const { return m_values.size(); }
    ConstRefType at(size_t index) const { return m_values[index]; }
    RefType at(size_t index) { return m_values[index]; }
    ConstRefType operator[](size_t index) const { return at(index); }
    RefType operator[](size_t index) { return at(index); }

    Operand operandForIndex(size_t index) const
    {
        if (index < numberOfArguments())
            return virtualRegisterForArgumentIncludingThis(index);
        else if (index < numberOfLocals() + numberOfArguments())
            return virtualRegisterForLocal(index - numberOfArguments());
        return Operand::tmp(index - (numberOfLocals() + numberOfArguments()));
    }

    void fill(T value)
    {
        for (size_t i = 0; i < m_values.size(); ++i)
            m_values[i] = value;
    }
    
    void clear()
    {
        fill(T());
    }
    
    bool operator==(const Operands& other) const
    {
        ASSERT(numberOfArguments() == other.numberOfArguments());
        ASSERT(numberOfLocals() == other.numberOfLocals());
        ASSERT(numberOfTmps() == other.numberOfTmps());
        
        return m_values == other.m_values;
    }
    
    void dumpInContext(PrintStream& out, DumpContext* context) const;
    void dump(PrintStream& out) const;
    
private:
    // The first m_numArguments of m_values are arguments, the next m_numLocals are locals, and the rest are tmps.
    Storage m_values;
    unsigned m_numArguments { 0 };
    unsigned m_numLocals { 0 };
};

} // namespace JSC
