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

#if ENABLE(DFG_JIT)

#include "DFGValueStrength.h"
#include "JSCJSValue.h"
#include "JSCast.h"
#include "Structure.h"

namespace JSC { namespace DFG {

class Graph;

class FrozenValue {
public:
    FrozenValue()
        : m_structure(nullptr)
        , m_strength(WeakValue)
    {
    }
    
    FrozenValue(JSValue value)
        : m_value(value)
        , m_structure(nullptr)
        , m_strength(WeakValue)
    {
        RELEASE_ASSERT(!value || !value.isCell());
    }
    
    FrozenValue(JSValue value, Structure* structure, ValueStrength strength)
        : m_value(value)
        , m_structure(structure)
        , m_strength(strength)
    {
        ASSERT((!!value && value.isCell()) == !!structure);
        ASSERT(!value || !value.isCell() || value.asCell()->classInfo() == structure->classInfoForCells());
        ASSERT(!!structure || (strength == WeakValue));
    }
    
    static FrozenValue* emptySingleton();
    
    bool operator!() const { return !m_value; }
    
    JSValue value() const { return m_value; }
    JSCell* cell() const { return m_value.asCell(); }
    
    template<typename T>
    T dynamicCast()
    {
        JSValue theValue = value();
        if (!theValue)
            return nullptr;
        return jsDynamicCast<T>(theValue);
    }
    template<typename T>
    T cast()
    {
        return jsCast<T>(value());
    }
    
    Structure* structure() const { return m_structure; }
    
    void strengthenTo(ValueStrength strength)
    {
        if (!!m_value && m_value.isCell())
            m_strength = merge(m_strength, strength);
    }
    
    bool pointsToHeap() const { return !!value() && value().isCell(); }
    
    // The strength of the value itself. The structure is almost always weak.
    ValueStrength strength() const { return m_strength; }

    String tryGetString(Graph&);
    
    void dumpInContext(PrintStream& out, DumpContext* context) const;
    void dump(PrintStream& out) const;
    
private:
    friend class Graph;
    
    // This is a utility method for DFG::Graph::freeze(). You should almost always call
    // Graph::freeze() directly. Calling this instead of Graph::freeze() can result in
    // the same constant being viewed as having different structures during the course
    // of compilation, which can sometimes cause bad things to happen. For example, we
    // may observe that one version of the constant has an unwatchable structure but
    // then a later version may start to have a watchable structure due to a transition.
    // The point of freezing is to ensure that we generally only see one version of
    // constants, but that requires freezing through the Graph.
    static FrozenValue freeze(JSValue value)
    {
        return FrozenValue(
            value,
            (!!value && value.isCell()) ? value.asCell()->structure() : nullptr,
            WeakValue);
    }

    JSValue m_value;
    Structure* m_structure;
    ValueStrength m_strength;
};

} } // namespace JSC::DFG

#endif // ENABLE(DFG_JIT)
