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

#include "config.h"
#include "DFGAbstractValue.h"

#if ENABLE(DFG_JIT)

#include "DFGGraph.h"
#include "JSCInlines.h"
#include "TrackedReferences.h"

namespace JSC { namespace DFG {

void AbstractValue::observeTransitions(const TransitionVector& vector)
{
    if (m_type & SpecCell) {
        m_structure.observeTransitions(vector);
        ArrayModes newModes = 0;
        for (unsigned i = vector.size(); i--;) {
            if (m_arrayModes & arrayModesFromStructure(vector[i].previous.get()))
                newModes |= arrayModesFromStructure(vector[i].next.get());
        }
        m_arrayModes |= newModes;
    }
    checkConsistency();
}

void AbstractValue::set(Graph& graph, const FrozenValue& value, StructureClobberState clobberState)
{
    if (!!value && value.value().isCell()) {
        Structure* structure = value.structure();
        StructureRegistrationResult result;
        RegisteredStructure registeredStructure = graph.registerStructure(structure, result);
        if (result == StructureRegisteredAndWatched) {
            m_structure = registeredStructure;
            if (clobberState == StructuresAreClobbered) {
                m_arrayModes = ALL_ARRAY_MODES;
                m_structure.clobber();
            } else
                m_arrayModes = arrayModesFromStructure(structure);
        } else {
            m_structure.makeTop();
            m_arrayModes = ALL_ARRAY_MODES;
        }
    } else {
        m_structure.clear();
        m_arrayModes = 0;
    }
    
    m_type = speculationFromValue(value.value());
    m_value = value.value();
    
    checkConsistency();
    assertIsRegistered(graph);
}

void AbstractValue::set(Graph& graph, Structure* structure)
{
    set(graph, graph.registerStructure(structure));
}

void AbstractValue::set(Graph& graph, RegisteredStructure structure)
{
    RELEASE_ASSERT(structure);
    
    m_structure = structure;
    m_arrayModes = arrayModesFromStructure(structure.get());
    m_type = speculationFromStructure(structure.get());
    m_value = JSValue();
    
    checkConsistency();
    assertIsRegistered(graph);
}

void AbstractValue::set(Graph& graph, const RegisteredStructureSet& set)
{
    m_structure = set;
    m_arrayModes = set.arrayModesFromStructures();
    m_type = set.speculationFromStructures();
    m_value = JSValue();
    
    checkConsistency();
    assertIsRegistered(graph);
}

void AbstractValue::setType(Graph& graph, SpeculatedType type)
{
    SpeculatedType cellType = type & SpecCell;
    if (cellType) {
        if (!(cellType & ~SpecString))
            m_structure = graph.stringStructure;
        else if (isSymbolSpeculation(cellType))
            m_structure = graph.symbolStructure;
        else
            m_structure.makeTop();
        m_arrayModes = ALL_ARRAY_MODES;
    } else {
        m_structure.clear();
        m_arrayModes = 0;
    }
    m_type = type;
    m_value = JSValue();
    checkConsistency();
}

void AbstractValue::fixTypeForRepresentation(Graph& graph, NodeFlags representation, Node* node)
{
    if (representation == NodeResultDouble) {
        if (m_value) {
            DFG_ASSERT(graph, node, m_value.isNumber());
            if (m_value.isInt32())
                m_value = jsDoubleNumber(m_value.asNumber());
        }
        if (m_type & SpecIntAnyFormat) {
            m_type &= ~SpecIntAnyFormat;
            m_type |= SpecAnyIntAsDouble;
        }
        if (m_type & ~SpecFullDouble)
            DFG_CRASH(graph, node, toCString("Abstract value ", *this, " for double node has type outside SpecFullDouble.\n").data());
    } else if (representation == NodeResultInt52) {
        if (m_type & SpecAnyIntAsDouble) {
            // AnyIntAsDouble can produce i32 or i52. SpecAnyIntAsDouble doesn't bound the magnitude of the value.
            m_type &= ~SpecAnyIntAsDouble;
            m_type |= SpecInt52Any;
        }

        if (m_type & SpecInt32Only) {
            m_type &= ~SpecInt32Only;
            m_type |= SpecInt32AsInt52;
        }

        if (m_type & ~SpecInt52Any)
            DFG_CRASH(graph, node, toCString("Abstract value ", *this, " for int52 node has type outside SpecInt52Any.\n").data());

        if (m_value) {
            DFG_ASSERT(graph, node, m_value.isAnyInt());
            m_type = int52AwareSpeculationFromValue(m_value);
        }
    } else {
        if (m_type & SpecInt32AsInt52) {
            m_type &= ~SpecInt32AsInt52;
            m_type |= SpecInt32Only;
        }
        if (m_type & SpecNonInt32AsInt52) {
            m_type &= ~SpecNonInt32AsInt52;
            m_type |= SpecAnyIntAsDouble;
        }
        if (m_type & ~SpecBytecodeTop)
            DFG_CRASH(graph, node, toCString("Abstract value ", *this, " for value node has type outside SpecBytecodeTop.\n").data());
    }
    
    checkConsistency();
}

void AbstractValue::fixTypeForRepresentation(Graph& graph, Node* node)
{
    fixTypeForRepresentation(graph, node->result(), node);
}

bool AbstractValue::mergeOSREntryValue(Graph& graph, JSValue value, VariableAccessData* variable, Node* node)
{
    FlushFormat flushFormat = variable->flushFormat();

    {
        if (flushFormat == FlushedDouble && value.isNumber())
            value = jsDoubleNumber(value.asNumber());
        SpeculatedType incomingType = resultFor(flushFormat) == NodeResultInt52 ? int52AwareSpeculationFromValue(value) : speculationFromValue(value);
        SpeculatedType requiredType = typeFilterFor(flushFormat);
        if (incomingType & ~requiredType)
            return false;
    }

    AbstractValue oldMe = *this;
    
    if (isClear()) {
        FrozenValue* frozenValue = graph.freeze(value);
        if (frozenValue->pointsToHeap()) {
            m_structure = graph.registerStructure(frozenValue->structure());
            m_arrayModes = arrayModesFromStructure(frozenValue->structure());
        } else {
            m_structure.clear();
            m_arrayModes = 0;
        }
        
        m_type = speculationFromValue(value);
        m_value = value;
    } else {
        mergeSpeculation(m_type, speculationFromValue(value));
        if (!!value && value.isCell()) {
            RegisteredStructure structure = graph.registerStructure(value.asCell()->structure(graph.m_vm));
            mergeArrayModes(m_arrayModes, arrayModesFromStructure(structure.get()));
            m_structure.merge(RegisteredStructureSet(structure));
        }
        if (m_value != value)
            m_value = JSValue();
    }
    
    assertIsRegistered(graph);

    fixTypeForRepresentation(graph, resultFor(flushFormat), node);

    checkConsistency();
    
    return oldMe != *this;
}

FiltrationResult AbstractValue::filter(
    Graph& graph, const RegisteredStructureSet& other, SpeculatedType admittedTypes)
{
    ASSERT(!(admittedTypes & SpecCell));
    
    if (isClear())
        return FiltrationOK;
    
    // FIXME: This could be optimized for the common case of m_type not
    // having structures, array modes, or a specific value.
    // https://bugs.webkit.org/show_bug.cgi?id=109663
    
    m_type &= other.speculationFromStructures() | admittedTypes;
    m_arrayModes &= other.arrayModesFromStructures();
    m_structure.filter(other);
    
    // It's possible that prior to the above two statements we had (Foo, TOP), where
    // Foo is a SpeculatedType that is disjoint with the passed RegisteredStructureSet. In that
    // case, we will now have (None, [someStructure]). In general, we need to make
    // sure that new information gleaned from the SpeculatedType needs to be fed back
    // into the information gleaned from the RegisteredStructureSet.
    m_structure.filter(m_type);
    
    filterArrayModesByType();
    filterValueByType();
    return normalizeClarity(graph);
}

FiltrationResult AbstractValue::changeStructure(Graph& graph, const RegisteredStructureSet& other)
{
    m_type &= other.speculationFromStructures();
    m_arrayModes = other.arrayModesFromStructures();
    m_structure = other;
    
    filterValueByType();
    
    return normalizeClarity(graph);
}

FiltrationResult AbstractValue::filterArrayModes(ArrayModes arrayModes)
{
    ASSERT(arrayModes);
    
    if (isClear())
        return FiltrationOK;
    
    m_type &= SpecCell;
    m_arrayModes &= arrayModes;
    return normalizeClarity();
}

FiltrationResult AbstractValue::filterClassInfo(Graph& graph, const ClassInfo* classInfo)
{
    // FIXME: AI should track ClassInfo to leverage hierarchical class information.
    // https://bugs.webkit.org/show_bug.cgi?id=162989
    if (isClear())
        return FiltrationOK;

    m_type &= speculationFromClassInfo(classInfo);
    m_structure.filterClassInfo(classInfo);

    m_structure.filter(m_type);

    filterArrayModesByType();
    filterValueByType();
    return normalizeClarity(graph);
}

FiltrationResult AbstractValue::filterSlow(SpeculatedType type)
{
    m_type &= type;
    
    // It's possible that prior to this filter() call we had, say, (Final, TOP), and
    // the passed type is Array. At this point we'll have (None, TOP). The best way
    // to ensure that the structure filtering does the right thing is to filter on
    // the new type (None) rather than the one passed (Array).
    m_structure.filter(m_type);
    filterArrayModesByType();
    filterValueByType();
    return normalizeClarity();
}

FiltrationResult AbstractValue::fastForwardToAndFilterSlow(AbstractValueClobberEpoch newEpoch, SpeculatedType type)
{
    if (newEpoch != m_effectEpoch)
        fastForwardToSlow(newEpoch);
    
    return filterSlow(type);
}

FiltrationResult AbstractValue::filterByValue(const FrozenValue& value)
{
    FiltrationResult result = filter(speculationFromValue(value.value()));
    if (m_type)
        m_value = value.value();
    return result;
}

bool AbstractValue::contains(RegisteredStructure structure) const
{
    return couldBeType(speculationFromStructure(structure.get()))
        && (m_arrayModes & arrayModesFromStructure(structure.get()))
        && m_structure.contains(structure);
}

FiltrationResult AbstractValue::filter(const AbstractValue& other)
{
    m_type &= other.m_type;
    m_structure.filter(other.m_structure);
    m_arrayModes &= other.m_arrayModes;

    m_structure.filter(m_type);
    filterArrayModesByType();
    filterValueByType();
    
    if (normalizeClarity() == Contradiction)
        return Contradiction;
    
    if (m_value == other.m_value)
        return FiltrationOK;
    
    // Neither of us are BOTTOM, so an empty value means TOP.
    if (!m_value) {
        // We previously didn't prove a value but now we have done so.
        m_value = other.m_value; 
        return FiltrationOK;
    }
    
    if (!other.m_value) {
        // We had proved a value but the other guy hadn't, so keep our proof.
        return FiltrationOK;
    }
    
    // We both proved there to be a specific value but they are different.
    clear();
    return Contradiction;
}

void AbstractValue::filterValueByType()
{
    // We could go further, and ensure that if the futurePossibleStructure contravenes
    // the value, then we could clear both of those things. But that's unlikely to help
    // in any realistic scenario, so we don't do it. Simpler is better.

    if (!m_value)
        return;

    if (validateTypeAcceptingBoxedInt52(m_value))
        return;

    // We assume that the constant value can produce a narrower type at
    // some point. For example, rope JSString produces SpecString, but
    // it produces SpecStringIdent once it is resolved to AtomStringImpl.
    // We do not make this AbstractValue cleared, but clear the constant
    // value if validation fails currently.
    m_value = JSValue();
}

void AbstractValue::filterArrayModesByType()
{
    if (!(m_type & SpecCell))
        m_arrayModes = 0;
    else if (!(m_type & ~SpecArray))
        m_arrayModes &= ALL_ARRAY_ARRAY_MODES;
    
    // NOTE: If m_type doesn't have SpecArray set, that doesn't mean that the
    // array modes have to be a subset of ALL_NON_ARRAY_ARRAY_MODES, since
    // in the speculated type type-system, RegExpMatchesArry and ArrayPrototype
    // are Otherobj (since they are not *exactly* JSArray) but in the ArrayModes
    // type system they are arrays (since they expose the magical length
    // property and are otherwise allocated using array allocation). Hence the
    // following would be wrong:
    //
    // if (!(m_type & SpecArray))
    //    m_arrayModes &= ALL_NON_ARRAY_ARRAY_MODES;
}

bool AbstractValue::shouldBeClear() const
{
    if (m_type == SpecNone)
        return true;
    
    if (!(m_type & ~SpecCell)
        && (!m_arrayModes || m_structure.isClear()))
        return true;
    
    return false;
}

FiltrationResult AbstractValue::normalizeClarity()
{
    // It's useful to be able to quickly check if an abstract value is clear.
    // This normalizes everything to make that easy.
    
    FiltrationResult result;
    
    if (shouldBeClear()) {
        clear();
        result = Contradiction;
    } else
        result = FiltrationOK;

    checkConsistency();
    
    return result;
}

FiltrationResult AbstractValue::normalizeClarity(Graph& graph)
{
    FiltrationResult result = normalizeClarity();
    assertIsRegistered(graph);
    return result;
}

#if !ASSERT_DISABLED
void AbstractValue::checkConsistency() const
{
    if (!(m_type & SpecCell)) {
        RELEASE_ASSERT(m_structure.isClear());
        RELEASE_ASSERT(!m_arrayModes);
    }
    
    if (isClear())
        RELEASE_ASSERT(!m_value);
    
    if (!!m_value)
        RELEASE_ASSERT(validateTypeAcceptingBoxedInt52(m_value));

    // Note that it's possible for a prediction like (Final, []). This really means that
    // the value is bottom and that any code that uses the value is unreachable. But
    // we don't want to get pedantic about this as it would only increase the computational
    // complexity of the code.
}

void AbstractValue::assertIsRegistered(Graph& graph) const
{
    m_structure.assertIsRegistered(graph);
}
#endif // !ASSERT_DISABLED

ResultType AbstractValue::resultType() const
{
    ASSERT(isType(SpecBytecodeTop));
    if (isType(SpecBoolean))
        return ResultType::booleanType();
    if (isType(SpecInt32Only))
        return ResultType::numberTypeIsInt32();
    if (isType(SpecBytecodeNumber))
        return ResultType::numberType();
    if (isType(SpecString))
        return ResultType::stringType();
    if (isType(SpecString | SpecBytecodeNumber))
        return ResultType::stringOrNumberType();
    return ResultType::unknownType();
}

void AbstractValue::dump(PrintStream& out) const
{
    dumpInContext(out, 0);
}

void AbstractValue::dumpInContext(PrintStream& out, DumpContext* context) const
{
    out.print("(", SpeculationDump(m_type));
    if (m_type & SpecCell) {
        out.print(
            ", ", ArrayModesDump(m_arrayModes), ", ",
            inContext(m_structure, context));
    }
    if (!!m_value)
        out.print(", ", inContext(m_value, context));
    out.print(", ", m_effectEpoch);
    out.print(")");
}

void AbstractValue::validateReferences(const TrackedReferences& trackedReferences)
{
    trackedReferences.check(m_value);
    m_structure.validateReferences(trackedReferences);
}

#if USE(JSVALUE64) && !defined(NDEBUG)
void AbstractValue::ensureCanInitializeWithZeros()
{
    std::aligned_storage<sizeof(AbstractValue), alignof(AbstractValue)>::type zeroFilledStorage;
    memset(static_cast<void*>(&zeroFilledStorage), 0, sizeof(AbstractValue));
    ASSERT(*this == *static_cast<AbstractValue*>(static_cast<void*>(&zeroFilledStorage)));
}
#endif

void AbstractValue::fastForwardToSlow(AbstractValueClobberEpoch newEpoch)
{
    ASSERT(newEpoch != m_effectEpoch);
    
    if (newEpoch.clobberEpoch() != m_effectEpoch.clobberEpoch())
        clobberStructures();
    if (newEpoch.structureClobberState() == StructuresAreWatched)
        m_structure.observeInvalidationPoint();
    
    m_effectEpoch = newEpoch;
    
    checkConsistency();
}

} } // namespace JSC::DFG

#endif // ENABLE(DFG_JIT)

