/*
 * 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(value.asCell()->vm()) == structure->classInfo());
        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(VM& vm)
    {
        JSValue theValue = value();
        if (!theValue)
            return nullptr;
        return jsDynamicCast<T>(vm, 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)
