/*
 * 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 {
    // 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;
        result.m_source.gpr = gpr;
        return result;
    }
    
#if USE(JSVALUE32_64)
    static ValueRecovery inPair(MacroAssembler::RegisterID tagGPR, MacroAssembler::RegisterID payloadGPR)
    {
        ValueRecovery result;
        result.m_technique = InPair;
        result.m_source.pair.tagGPR = tagGPR;
        result.m_source.pair.payloadGPR = payloadGPR;
        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;
        result.m_source.fpr = fpr;
        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;
        }
        result.m_source.virtualReg = virtualReg.offset();
        return result;
    }
    
    static ValueRecovery constant(JSValue value)
    {
        ValueRecovery result;
        result.m_technique = Constant;
        result.m_source.constant = JSValue::encode(value);
        return result;
    }
    
    static ValueRecovery directArgumentsThatWereNotCreated(DFG::MinifiedID id)
    {
        ValueRecovery result;
        result.m_technique = DirectArgumentsThatWereNotCreated;
        result.m_source.nodeID = id.bits();
        return result;
    }
    
    static ValueRecovery clonedArgumentsThatWereNotCreated(DFG::MinifiedID id)
    {
        ValueRecovery result;
        result.m_technique = ClonedArgumentsThatWereNotCreated;
        result.m_source.nodeID = id.bits();
        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.gpr;
    }
    
#if USE(JSVALUE32_64)
    MacroAssembler::RegisterID tagGPR() const
    {
        ASSERT(m_technique == InPair);
        return m_source.pair.tagGPR;
    }
    
    MacroAssembler::RegisterID payloadGPR() const
    {
        ASSERT(m_technique == InPair);
        return m_source.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.fpr;
    }
    
    VirtualRegister virtualRegister() const
    {
        ASSERT(isInJSStack());
        return VirtualRegister(m_source.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;
            result.m_source.virtualReg = m_source.virtualReg + offset;
            return result;
        }
            
        default:
            return *this;
        }
    }
    
    JSValue constant() const
    {
        ASSERT(isConstant());
        return JSValue::decode(m_source.constant);
    }
    
    DFG::MinifiedID nodeID() const
    {
        ASSERT(m_technique == DirectArgumentsThatWereNotCreated || m_technique == ClonedArgumentsThatWereNotCreated);
        return DFG::MinifiedID::fromBits(m_source.nodeID);
    }
    
    JSValue recover(ExecState*) 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 {
        MacroAssembler::RegisterID gpr;
        MacroAssembler::FPRegisterID fpr;
#if USE(JSVALUE32_64)
        struct {
            MacroAssembler::RegisterID tagGPR;
            MacroAssembler::RegisterID payloadGPR;
        } pair;
#endif
        int virtualReg;
        EncodedJSValue constant;
        uintptr_t nodeID;
    } m_source;
};

} // namespace JSC
