/*
 * Copyright (C) 2011, 2013, 2015 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 "DFGMinifiedID.h"
#include "DataFormat.h"
#if ENABLE(JIT)
#include "GPRInfo.h"
#include "FPRInfo.h"
#include "Reg.h"
#endif
#include "JSCJSValue.h"
#include "MacroAssembler.h"
#include "VirtualRegister.h"

namespace JSC {

struct DumpContext;
struct InlineCallFrame;

// Describes how to recover a given bytecode virtual register at a given
// code point.
enum ValueRecoveryTechnique : uint8_t {
    // It's in a register.
    InGPR,
    UnboxedInt32InGPR,
    UnboxedInt52InGPR,
    UnboxedStrictInt52InGPR,
    UnboxedBooleanInGPR,
    UnboxedCellInGPR,
#if USE(JSVALUE32_64)
    InPair,
#endif
    InFPR,
    UnboxedDoubleInFPR,
    // It's in the stack, but at a different location.
    DisplacedInJSStack,
    // It's in the stack, at a different location, and it's unboxed.
    Int32DisplacedInJSStack,
    Int52DisplacedInJSStack,
    StrictInt52DisplacedInJSStack,
    DoubleDisplacedInJSStack,
    CellDisplacedInJSStack,
    BooleanDisplacedInJSStack,
    // It's an Arguments object. This arises because of the simplified arguments simplification done by the DFG.
    DirectArgumentsThatWereNotCreated,
    ClonedArgumentsThatWereNotCreated,
    // It's a constant.
    Constant,
    // Don't know how to recover it.
    DontKnow
};

class ValueRecovery {
public:
    ValueRecovery()
        : m_technique(DontKnow)
    {
    }
    
    bool isSet() const { return m_technique != DontKnow; }
    bool operator!() const { return !isSet(); }

#if ENABLE(JIT)
    static ValueRecovery inRegister(Reg reg, DataFormat dataFormat)
    {
        if (reg.isGPR())
            return inGPR(reg.gpr(), dataFormat);

        ASSERT(reg.isFPR());
        return inFPR(reg.fpr(), dataFormat);
    }
#endif

    explicit operator bool() const { return isSet(); }
    
    static ValueRecovery inGPR(MacroAssembler::RegisterID gpr, DataFormat dataFormat)
    {
        ASSERT(dataFormat != DataFormatNone);
#if USE(JSVALUE32_64)
        ASSERT(dataFormat == DataFormatInt32 || dataFormat == DataFormatCell || dataFormat == DataFormatBoolean);
#endif
        ValueRecovery result;
        if (dataFormat == DataFormatInt32)
            result.m_technique = UnboxedInt32InGPR;
        else if (dataFormat == DataFormatInt52)
            result.m_technique = UnboxedInt52InGPR;
        else if (dataFormat == DataFormatStrictInt52)
            result.m_technique = UnboxedStrictInt52InGPR;
        else if (dataFormat == DataFormatBoolean)
            result.m_technique = UnboxedBooleanInGPR;
        else if (dataFormat == DataFormatCell)
            result.m_technique = UnboxedCellInGPR;
        else
            result.m_technique = InGPR;
        UnionType u;
        u.gpr = gpr;
        result.m_source = WTFMove(u);
        return result;
    }
    
#if USE(JSVALUE32_64)
    static ValueRecovery inPair(MacroAssembler::RegisterID tagGPR, MacroAssembler::RegisterID payloadGPR)
    {
        ValueRecovery result;
        result.m_technique = InPair;
        UnionType u;
        u.pair.tagGPR = tagGPR;
        u.pair.payloadGPR = payloadGPR;
        result.m_source = WTFMove(u);
        return result;
    }
#endif

    static ValueRecovery inFPR(MacroAssembler::FPRegisterID fpr, DataFormat dataFormat)
    {
        ASSERT(dataFormat == DataFormatDouble || dataFormat & DataFormatJS);
        ValueRecovery result;
        if (dataFormat == DataFormatDouble)
            result.m_technique = UnboxedDoubleInFPR;
        else
            result.m_technique = InFPR;
        UnionType u;
        u.fpr = fpr;
        result.m_source = WTFMove(u);
        return result;
    }
    
    static ValueRecovery displacedInJSStack(VirtualRegister virtualReg, DataFormat dataFormat)
    {
        ValueRecovery result;
        switch (dataFormat) {
        case DataFormatInt32:
            result.m_technique = Int32DisplacedInJSStack;
            break;
            
        case DataFormatInt52:
            result.m_technique = Int52DisplacedInJSStack;
            break;
            
        case DataFormatStrictInt52:
            result.m_technique = StrictInt52DisplacedInJSStack;
            break;
            
        case DataFormatDouble:
            result.m_technique = DoubleDisplacedInJSStack;
            break;

        case DataFormatCell:
            result.m_technique = CellDisplacedInJSStack;
            break;
            
        case DataFormatBoolean:
            result.m_technique = BooleanDisplacedInJSStack;
            break;
            
        default:
            ASSERT(dataFormat != DataFormatNone && dataFormat != DataFormatStorage);
            result.m_technique = DisplacedInJSStack;
            break;
        }
        UnionType u;
        u.virtualReg = virtualReg.offset();
        result.m_source = WTFMove(u);
        return result;
    }
    
    static ValueRecovery constant(JSValue value)
    {
        ValueRecovery result;
        result.m_technique = Constant;
        UnionType u;
        u.constant = JSValue::encode(value);
        result.m_source = WTFMove(u);
        return result;
    }
    
    static ValueRecovery directArgumentsThatWereNotCreated(DFG::MinifiedID id)
    {
        ValueRecovery result;
        result.m_technique = DirectArgumentsThatWereNotCreated;
        UnionType u;
        u.nodeID = id.bits();
        result.m_source = WTFMove(u);
        return result;
    }
    
    static ValueRecovery clonedArgumentsThatWereNotCreated(DFG::MinifiedID id)
    {
        ValueRecovery result;
        result.m_technique = ClonedArgumentsThatWereNotCreated;
        UnionType u;
        u.nodeID = id.bits();
        result.m_source = WTFMove(u);
        return result;
    }

    ValueRecoveryTechnique technique() const { return m_technique; }
    
    bool isConstant() const { return m_technique == Constant; }

    bool isInGPR() const
    {
        switch (m_technique) {
        case InGPR:
        case UnboxedInt32InGPR:
        case UnboxedBooleanInGPR:
        case UnboxedCellInGPR:
        case UnboxedInt52InGPR:
        case UnboxedStrictInt52InGPR:
            return true;
        default:
            return false;
        }
    }

    bool isInFPR() const
    {
        switch (m_technique) {
        case InFPR:
        case UnboxedDoubleInFPR:
            return true;
        default:
            return false;
        }
    }

    bool isInRegisters() const
    {
        return isInJSValueRegs() || isInGPR() || isInFPR();
    }

    bool isInJSStack() const
    {
        switch (m_technique) {
        case DisplacedInJSStack:
        case Int32DisplacedInJSStack:
        case Int52DisplacedInJSStack:
        case StrictInt52DisplacedInJSStack:
        case DoubleDisplacedInJSStack:
        case CellDisplacedInJSStack:
        case BooleanDisplacedInJSStack:
            return true;
        default:
            return false;
        }
    }

    DataFormat dataFormat() const
    {
        switch (m_technique) {
        case InGPR:
        case InFPR:
        case DisplacedInJSStack:
        case Constant:
#if USE(JSVALUE32_64)
        case InPair:
#endif
            return DataFormatJS;
        case UnboxedInt32InGPR:
        case Int32DisplacedInJSStack:
            return DataFormatInt32;
        case UnboxedInt52InGPR:
        case Int52DisplacedInJSStack:
            return DataFormatInt52;
        case UnboxedStrictInt52InGPR:
        case StrictInt52DisplacedInJSStack:
            return DataFormatStrictInt52;
        case UnboxedBooleanInGPR:
        case BooleanDisplacedInJSStack:
            return DataFormatBoolean;
        case UnboxedCellInGPR:
        case CellDisplacedInJSStack:
            return DataFormatCell;
        case UnboxedDoubleInFPR:
        case DoubleDisplacedInJSStack:
            return DataFormatDouble;
        default:
            return DataFormatNone;
        }
    }
    
    MacroAssembler::RegisterID gpr() const
    {
        ASSERT(isInGPR());
        return m_source.get().gpr;
    }
    
#if USE(JSVALUE32_64)
    MacroAssembler::RegisterID tagGPR() const
    {
        ASSERT(m_technique == InPair);
        return m_source.get().pair.tagGPR;
    }
    
    MacroAssembler::RegisterID payloadGPR() const
    {
        ASSERT(m_technique == InPair);
        return m_source.get().pair.payloadGPR;
    }

    bool isInJSValueRegs() const
    {
        return m_technique == InPair;
    }

#if ENABLE(JIT)
    JSValueRegs jsValueRegs() const
    {
        ASSERT(isInJSValueRegs());
        return JSValueRegs(tagGPR(), payloadGPR());
    }
#endif // ENABLE(JIT)
#else
    bool isInJSValueRegs() const
    {
        return isInGPR();
    }
#endif // USE(JSVALUE32_64)
    
    MacroAssembler::FPRegisterID fpr() const
    {
        ASSERT(isInFPR());
        return m_source.get().fpr;
    }
    
    VirtualRegister virtualRegister() const
    {
        ASSERT(isInJSStack());
        return VirtualRegister(m_source.get().virtualReg);
    }
    
    ValueRecovery withLocalsOffset(int offset) const
    {
        switch (m_technique) {
        case DisplacedInJSStack:
        case Int32DisplacedInJSStack:
        case DoubleDisplacedInJSStack:
        case CellDisplacedInJSStack:
        case BooleanDisplacedInJSStack:
        case Int52DisplacedInJSStack:
        case StrictInt52DisplacedInJSStack: {
            ValueRecovery result;
            result.m_technique = m_technique;
            UnionType u;
            u.virtualReg = m_source.get().virtualReg + offset;
            result.m_source = WTFMove(u);
            return result;
        }
            
        default:
            return *this;
        }
    }
    
    JSValue constant() const
    {
        ASSERT(isConstant());
        return JSValue::decode(m_source.get().constant);
    }
    
    DFG::MinifiedID nodeID() const
    {
        ASSERT(m_technique == DirectArgumentsThatWereNotCreated || m_technique == ClonedArgumentsThatWereNotCreated);
        return DFG::MinifiedID::fromBits(m_source.get().nodeID);
    }
    
    JSValue recover(CallFrame*) const;
    
#if ENABLE(JIT)
    template<typename Func>
    void forEachReg(const Func& func)
    {
        switch (m_technique) {
        case InGPR:
        case UnboxedInt32InGPR:
        case UnboxedBooleanInGPR:
        case UnboxedCellInGPR:
        case UnboxedInt52InGPR:
        case UnboxedStrictInt52InGPR:
            func(gpr());
            return;
        case InFPR:
        case UnboxedDoubleInFPR:
            func(fpr());
            return;
#if USE(JSVALUE32_64)
        case InPair:
            func(jsValueRegs().payloadGPR());
            func(jsValueRegs().tagGPR());
            return;
#endif
        default:
            return;
        }
    }
    
    void dumpInContext(PrintStream& out, DumpContext* context) const;
    void dump(PrintStream& out) const;
#endif

private:
    ValueRecoveryTechnique m_technique;
    union UnionType {
        MacroAssembler::RegisterID gpr;
        MacroAssembler::FPRegisterID fpr;
#if USE(JSVALUE32_64)
        struct {
            MacroAssembler::RegisterID tagGPR;
            MacroAssembler::RegisterID payloadGPR;
        } pair;
#endif
        int virtualReg;
        EncodedJSValue constant;
        unsigned nodeID;
    };
    Packed<UnionType> m_source;
};
static_assert(alignof(ValueRecovery) == 1);

} // namespace JSC
