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

#if ENABLE(DFG_JIT)

#include "ArrayProfile.h"
#include "SpeculatedType.h"

namespace JSC {

class CodeOrigin;

namespace DFG {

class Graph;
struct AbstractValue;
struct Node;

// Use a namespace + enum instead of enum alone to avoid the namespace collision
// that would otherwise occur, since we say things like "Int8Array" and "JSArray"
// in lots of other places, to mean subtly different things.
namespace Array {
enum Action : uint8_t {
    Read,
    Write
};

enum Type : uint8_t {
    SelectUsingPredictions, // Implies that we need predictions to decide. We will never get to the backend in this mode.
    SelectUsingArguments, // Implies that we use the Node's arguments to decide. We will never get to the backend in this mode.
    Unprofiled, // Implies that array profiling didn't see anything. But that could be because the operands didn't comply with basic type assumptions (base is cell, property is int). This either becomes Generic or ForceExit depending on value profiling.
    ForceExit, // Implies that we have no idea how to execute this operation, so we should just give up.
    Generic,
    String,

    Undecided,
    Int32,
    Double,
    Contiguous,
    ArrayStorage,
    SlowPutArrayStorage,
    
    DirectArguments,
    ScopedArguments,
    
    Int8Array,
    Int16Array,
    Int32Array,
    Uint8Array,
    Uint8ClampedArray,
    Uint16Array,
    Uint32Array,
    Float32Array,
    Float64Array,
    AnyTypedArray
};

enum Class : uint8_t {
    NonArray, // Definitely some object that is not a JSArray.
    OriginalNonArray, // Definitely some object that is not a JSArray, but that object has the original structure.
    Array, // Definitely a JSArray, and may or may not have custom properties or have undergone some other bizarre transitions.
    OriginalArray, // Definitely a JSArray, and still has one of the primordial JSArray structures for the global object that this code block (possibly inlined code block) belongs to.
    OriginalCopyOnWriteArray, // Definitely a copy on write JSArray, and still has one of the primordial JSArray copy on write structures for the global object that this code block (possibly inlined code block) belongs to.
    PossiblyArray // Some object that may or may not be a JSArray.
};

enum Speculation : uint8_t {
    SaneChain, // In bounds and the array prototype chain is still intact, i.e. loading a hole doesn't require special treatment.
    
    InBounds, // In bounds and not loading a hole.
    ToHole, // Potentially storing to a hole.
    OutOfBounds // Out-of-bounds access and anything can happen.
};
enum Conversion : uint8_t {
    AsIs,
    Convert
};
} // namespace Array

const char* arrayActionToString(Array::Action);
const char* arrayTypeToString(Array::Type);
const char* arrayClassToString(Array::Class);
const char* arraySpeculationToString(Array::Speculation);
const char* arrayConversionToString(Array::Conversion);

IndexingType toIndexingShape(Array::Type);

TypedArrayType toTypedArrayType(Array::Type);
Array::Type toArrayType(TypedArrayType);
Array::Type refineTypedArrayType(Array::Type, TypedArrayType);

bool permitsBoundsCheckLowering(Array::Type);

class ArrayMode {
public:
    ArrayMode()
    {
        u.asBytes.type = Array::SelectUsingPredictions;
        u.asBytes.arrayClass = Array::NonArray;
        u.asBytes.speculation = Array::InBounds;
        u.asBytes.conversion = Array::AsIs;
        u.asBytes.action = Array::Write;
    }
    
    explicit ArrayMode(Array::Type type, Array::Action action)
    {
        u.asBytes.type = type;
        u.asBytes.arrayClass = Array::NonArray;
        u.asBytes.speculation = Array::InBounds;
        u.asBytes.conversion = Array::AsIs;
        u.asBytes.action = action;
    }
    
    ArrayMode(Array::Type type, Array::Class arrayClass, Array::Action action)
    {
        u.asBytes.type = type;
        u.asBytes.arrayClass = arrayClass;
        u.asBytes.speculation = Array::InBounds;
        u.asBytes.conversion = Array::AsIs;
        u.asBytes.action = action;
    }
    
    ArrayMode(Array::Type type, Array::Class arrayClass, Array::Speculation speculation, Array::Conversion conversion, Array::Action action)
    {
        u.asBytes.type = type;
        u.asBytes.arrayClass = arrayClass;
        u.asBytes.speculation = speculation;
        u.asBytes.conversion = conversion;
        u.asBytes.action = action;
    }
    
    ArrayMode(Array::Type type, Array::Class arrayClass, Array::Conversion conversion, Array::Action action)
    {
        u.asBytes.type = type;
        u.asBytes.arrayClass = arrayClass;
        u.asBytes.speculation = Array::InBounds;
        u.asBytes.conversion = conversion;
        u.asBytes.action = action;
    }
    
    Array::Type type() const { return static_cast<Array::Type>(u.asBytes.type); }
    Array::Class arrayClass() const { return static_cast<Array::Class>(u.asBytes.arrayClass); }
    Array::Speculation speculation() const { return static_cast<Array::Speculation>(u.asBytes.speculation); }
    Array::Conversion conversion() const { return static_cast<Array::Conversion>(u.asBytes.conversion); }
    Array::Action action() const { return static_cast<Array::Action>(u.asBytes.action); }
    
    unsigned asWord() const { return u.asWord; }
    
    static ArrayMode fromWord(unsigned word)
    {
        return ArrayMode(word);
    }
    
    static ArrayMode fromObserved(const ConcurrentJSLocker&, ArrayProfile*, Array::Action, bool makeSafe);
    
    ArrayMode withSpeculation(Array::Speculation speculation) const
    {
        return ArrayMode(type(), arrayClass(), speculation, conversion(), action());
    }
    
    ArrayMode withArrayClass(Array::Class arrayClass) const
    {
        return ArrayMode(type(), arrayClass, speculation(), conversion(), action());
    }
    
    ArrayMode withSpeculationFromProfile(const ConcurrentJSLocker& locker, ArrayProfile* profile, bool makeSafe) const
    {
        Array::Speculation mySpeculation;

        if (makeSafe)
            mySpeculation = Array::OutOfBounds;
        else if (profile->mayStoreToHole(locker))
            mySpeculation = Array::ToHole;
        else
            mySpeculation = Array::InBounds;
        
        return withSpeculation(mySpeculation);
    }
    
    ArrayMode withProfile(const ConcurrentJSLocker& locker, ArrayProfile* profile, bool makeSafe) const
    {
        Array::Class myArrayClass;

        if (isJSArray()) {
            if (profile->usesOriginalArrayStructures(locker) && benefitsFromOriginalArray()) {
                ArrayModes arrayModes = profile->observedArrayModes(locker);
                if (hasSeenCopyOnWriteArray(arrayModes) && !hasSeenWritableArray(arrayModes))
                    myArrayClass = Array::OriginalCopyOnWriteArray;
                else if (!hasSeenCopyOnWriteArray(arrayModes) && hasSeenWritableArray(arrayModes))
                    myArrayClass = Array::OriginalArray;
                else
                    myArrayClass = Array::Array;
            } else
                myArrayClass = Array::Array;
        } else
            myArrayClass = arrayClass();
        
        return withArrayClass(myArrayClass).withSpeculationFromProfile(locker, profile, makeSafe);
    }
    
    ArrayMode withType(Array::Type type) const
    {
        return ArrayMode(type, arrayClass(), speculation(), conversion(), action());
    }
    
    ArrayMode withConversion(Array::Conversion conversion) const
    {
        return ArrayMode(type(), arrayClass(), speculation(), conversion, action());
    }
    
    ArrayMode withTypeAndConversion(Array::Type type, Array::Conversion conversion) const
    {
        return ArrayMode(type, arrayClass(), speculation(), conversion, action());
    }
    
    static constexpr SpeculatedType unusedIndexSpeculatedType = SpecInt32Only;
    ArrayMode refine(Graph&, Node*, SpeculatedType base, SpeculatedType index, SpeculatedType value = SpecNone) const;
    
    bool alreadyChecked(Graph&, Node*, const AbstractValue&) const;
    
    void dump(PrintStream&) const;
    
    bool usesButterfly() const
    {
        switch (type()) {
        case Array::Undecided:
        case Array::Int32:
        case Array::Double:
        case Array::Contiguous:
        case Array::ArrayStorage:
        case Array::SlowPutArrayStorage:
            return true;
        default:
            return false;
        }
    }
    
    bool isJSArray() const
    {
        switch (arrayClass()) {
        case Array::Array:
        case Array::OriginalArray:
        case Array::OriginalCopyOnWriteArray:
            return true;
        default:
            return false;
        }
    }
    
    bool isJSArrayWithOriginalStructure() const
    {
        return arrayClass() == Array::OriginalArray || arrayClass() == Array::OriginalCopyOnWriteArray;
    }
    
    bool isSaneChain() const
    {
        return speculation() == Array::SaneChain;
    }
    
    bool isInBounds() const
    {
        switch (speculation()) {
        case Array::SaneChain:
        case Array::InBounds:
            return true;
        default:
            return false;
        }
    }
    
    bool mayStoreToHole() const
    {
        return !isInBounds();
    }
    
    bool isOutOfBounds() const
    {
        return speculation() == Array::OutOfBounds;
    }
    
    bool isSlowPut() const
    {
        return type() == Array::SlowPutArrayStorage;
    }

    bool canCSEStorage() const
    {
        switch (type()) {
        case Array::SelectUsingPredictions:
        case Array::SelectUsingArguments:
        case Array::Unprofiled:
        case Array::Undecided:
        case Array::ForceExit:
        case Array::Generic:
        case Array::DirectArguments:
        case Array::ScopedArguments:
            return false;
        default:
            return true;
        }
    }
    
    bool lengthNeedsStorage() const
    {
        switch (type()) {
        case Array::Undecided:
        case Array::Int32:
        case Array::Double:
        case Array::Contiguous:
        case Array::ArrayStorage:
        case Array::SlowPutArrayStorage:
            return true;
        default:
            return false;
        }
    }
    
    ArrayMode modeForPut() const
    {
        switch (type()) {
        case Array::String:
        case Array::DirectArguments:
        case Array::ScopedArguments:
            return ArrayMode(Array::Generic);
        default:
            return *this;
        }
    }
    
    bool isSpecific() const
    {
        switch (type()) {
        case Array::SelectUsingPredictions:
        case Array::SelectUsingArguments:
        case Array::Unprofiled:
        case Array::ForceExit:
        case Array::Generic:
            return false;
        default:
            return true;
        }
    }
    
    bool supportsSelfLength() const
    {
        switch (type()) {
        case Array::SelectUsingPredictions:
        case Array::Unprofiled:
        case Array::ForceExit:
        case Array::Generic:
        // TypedArrays do not have a self length property as of ES6.
        case Array::Int8Array:
        case Array::Int16Array:
        case Array::Int32Array:
        case Array::Uint8Array:
        case Array::Uint8ClampedArray:
        case Array::Uint16Array:
        case Array::Uint32Array:
        case Array::Float32Array:
        case Array::Float64Array:
            return false;
        case Array::Int32:
        case Array::Double:
        case Array::Contiguous:
        case Array::ArrayStorage:
        case Array::SlowPutArrayStorage:
            return isJSArray();
        default:
            return true;
        }
    }
    
    bool permitsBoundsCheckLowering() const;
    
    bool benefitsFromOriginalArray() const
    {
        switch (type()) {
        case Array::Int32:
        case Array::Double:
        case Array::Contiguous:
        case Array::Undecided:
        case Array::ArrayStorage:
            return true;
        default:
            return false;
        }
    }
    
    // Returns 0 if this is not OriginalArray.
    Structure* originalArrayStructure(Graph&, const CodeOrigin&) const;
    Structure* originalArrayStructure(Graph&, Node*) const;
    
    bool doesConversion() const
    {
        return conversion() != Array::AsIs;
    }

    bool structureWouldPassArrayModeFiltering(Structure* structure)
    {
        return arrayModesAlreadyChecked(arrayModesFromStructure(structure), arrayModesThatPassFiltering());
    }
    
    ArrayModes arrayModesThatPassFiltering() const
    {
        ArrayModes result;
        switch (type()) {
        case Array::Generic:
            return ALL_ARRAY_MODES;
        case Array::Undecided:
            return arrayModesWithIndexingShapes(UndecidedShape);
        case Array::Int32:
            result = arrayModesWithIndexingShapes(Int32Shape);
            break;
        case Array::Double:
            result = arrayModesWithIndexingShapes(DoubleShape);
            break;
        case Array::Contiguous:
            result = arrayModesWithIndexingShapes(ContiguousShape);
            break;
        case Array::ArrayStorage:
            return arrayModesWithIndexingShapes(ArrayStorageShape);
        case Array::SlowPutArrayStorage:
            return arrayModesWithIndexingShapes(SlowPutArrayStorageShape, ArrayStorageShape);
        case Array::DirectArguments:
        case Array::ScopedArguments:
            return arrayModesWithIndexingShapes(ArrayStorageShape, SlowPutArrayStorageShape, NonArray);
        case Array::Int8Array:
            return Int8ArrayMode;
        case Array::Int16Array:
            return Int16ArrayMode;
        case Array::Int32Array:
            return Int32ArrayMode;
        case Array::Uint8Array:
            return Uint8ArrayMode;
        case Array::Uint8ClampedArray:
            return Uint8ClampedArrayMode;
        case Array::Uint16Array:
            return Uint16ArrayMode;
        case Array::Uint32Array:
            return Uint32ArrayMode;
        case Array::Float32Array:
            return Float32ArrayMode;
        case Array::Float64Array:
            return Float64ArrayMode;
        case Array::AnyTypedArray:
            return ALL_TYPED_ARRAY_MODES;
        default:
            return asArrayModesIgnoringTypedArrays(NonArray);
        }

        if (action() == Array::Write)
            result &= ~ALL_COPY_ON_WRITE_ARRAY_MODES;
        return result;
    }
    
    bool getIndexedPropertyStorageMayTriggerGC() const
    {
        return type() == Array::String;
    }
    
    IndexingType shapeMask() const
    {
        return toIndexingShape(type());
    }
    
    TypedArrayType typedArrayType() const
    {
        return toTypedArrayType(type());
    }

    bool isSomeTypedArrayView() const
    {
        return type() == Array::AnyTypedArray || isTypedView(typedArrayType());
    }
    
    bool operator==(const ArrayMode& other) const
    {
        return type() == other.type()
            && arrayClass() == other.arrayClass()
            && speculation() == other.speculation()
            && conversion() == other.conversion();
    }
    
    bool operator!=(const ArrayMode& other) const
    {
        return !(*this == other);
    }
private:
    explicit ArrayMode(unsigned word)
    {
        u.asWord = word;
    }
    
    ArrayModes arrayModesWithIndexingShapes(IndexingType shape) const
    {
        switch (arrayClass()) {
        case Array::NonArray:
        case Array::OriginalNonArray:
            return asArrayModesIgnoringTypedArrays(shape);
        case Array::OriginalCopyOnWriteArray:
            ASSERT(hasInt32(shape) || hasDouble(shape) || hasContiguous(shape));
            return asArrayModesIgnoringTypedArrays(shape | IsArray) | asArrayModesIgnoringTypedArrays(shape | IsArray | CopyOnWrite);
        case Array::Array:
            if (hasInt32(shape) || hasDouble(shape) || hasContiguous(shape))
                return asArrayModesIgnoringTypedArrays(shape | IsArray) | asArrayModesIgnoringTypedArrays(shape | IsArray | CopyOnWrite);
            FALLTHROUGH;
        case Array::OriginalArray:
            return asArrayModesIgnoringTypedArrays(shape | IsArray);
        case Array::PossiblyArray:
            if (hasInt32(shape) || hasDouble(shape) || hasContiguous(shape))
                return asArrayModesIgnoringTypedArrays(shape) | asArrayModesIgnoringTypedArrays(shape | IsArray) | asArrayModesIgnoringTypedArrays(shape | IsArray | CopyOnWrite);
            return asArrayModesIgnoringTypedArrays(shape) | asArrayModesIgnoringTypedArrays(shape | IsArray);
        }
        // This is only necessary for C++ compilers that don't understand enums.
        return 0;
    }
    
    template <typename... Args>
    ArrayModes arrayModesWithIndexingShapes(IndexingType shape1, Args... args) const
    {
        ArrayModes arrayMode1 = arrayModesWithIndexingShapes(shape1);
        ArrayModes arrayMode2 = arrayModesWithIndexingShapes(args...);
        return arrayMode1 | arrayMode2;
    }

    bool alreadyChecked(Graph&, Node*, const AbstractValue&, IndexingType shape) const;
    
    union {
        struct {
            uint8_t type;
            uint8_t arrayClass;
            uint8_t speculation;
            uint8_t conversion : 4;
            uint8_t action : 4;
        } asBytes;
        unsigned asWord;
    } u;
    static_assert(sizeof(decltype(u.asBytes)) == sizeof(decltype(u.asWord)), "the word form of ArrayMode should have the same size as the individual slices");
};

static inline bool canCSEStorage(const ArrayMode& arrayMode)
{
    return arrayMode.canCSEStorage();
}

static inline bool lengthNeedsStorage(const ArrayMode& arrayMode)
{
    return arrayMode.lengthNeedsStorage();
}

static inline bool neverNeedsStorage(const ArrayMode&)
{
    return false;
}

} } // namespace JSC::DFG

namespace WTF {

class PrintStream;
void printInternal(PrintStream&, JSC::DFG::Array::Action);
void printInternal(PrintStream&, JSC::DFG::Array::Type);
void printInternal(PrintStream&, JSC::DFG::Array::Class);
void printInternal(PrintStream&, JSC::DFG::Array::Speculation);
void printInternal(PrintStream&, JSC::DFG::Array::Conversion);

} // namespace WTF

#endif // ENABLE(DFG_JIT)
