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

#pragma once

#include "ClassInfo.h"
#include "CodeLocation.h"
#include "IndexingType.h"
#include "JITStubRoutine.h"
#include "Structure.h"

namespace JSC {

class Symbol;

#if ENABLE(JIT)

class StructureStubInfo;

enum JITArrayMode : uint8_t {
    JITInt32,
    JITDouble,
    JITContiguous,
    JITArrayStorage,
    JITDirectArguments,
    JITScopedArguments,
    JITInt8Array,
    JITInt16Array,
    JITInt32Array,
    JITUint8Array,
    JITUint8ClampedArray,
    JITUint16Array,
    JITUint32Array,
    JITFloat32Array,
    JITFloat64Array
};

inline bool isOptimizableIndexingType(IndexingType indexingType)
{
    switch (indexingType) {
    case ALL_INT32_INDEXING_TYPES:
    case ALL_DOUBLE_INDEXING_TYPES:
    case ALL_CONTIGUOUS_INDEXING_TYPES:
    case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES:
        return true;
    default:
        return false;
    }
}

inline bool hasOptimizableIndexingForJSType(JSType type)
{
    switch (type) {
    case DirectArgumentsType:
    case ScopedArgumentsType:
        return true;
    default:
        return false;
    }
}

inline bool hasOptimizableIndexingForClassInfo(const ClassInfo* classInfo)
{
    return isTypedView(classInfo->typedArrayStorageType);
}

inline bool hasOptimizableIndexing(Structure* structure)
{
    return isOptimizableIndexingType(structure->indexingType())
        || hasOptimizableIndexingForJSType(structure->typeInfo().type())
        || hasOptimizableIndexingForClassInfo(structure->classInfo());
}

inline JITArrayMode jitArrayModeForIndexingType(IndexingType indexingType)
{
    switch (indexingType) {
    case ALL_INT32_INDEXING_TYPES:
        return JITInt32;
    case ALL_DOUBLE_INDEXING_TYPES:
        return JITDouble;
    case ALL_CONTIGUOUS_INDEXING_TYPES:
        return JITContiguous;
    case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES:
        return JITArrayStorage;
    default:
        CRASH();
        return JITContiguous;
    }
}

inline JITArrayMode jitArrayModeForJSType(JSType type)
{
    switch (type) {
    case DirectArgumentsType:
        return JITDirectArguments;
    case ScopedArgumentsType:
        return JITScopedArguments;
    default:
        RELEASE_ASSERT_NOT_REACHED();
        return JITContiguous;
    }
}

inline JITArrayMode jitArrayModeForClassInfo(const ClassInfo* classInfo)
{
    switch (classInfo->typedArrayStorageType) {
    case TypeInt8:
        return JITInt8Array;
    case TypeInt16:
        return JITInt16Array;
    case TypeInt32:
        return JITInt32Array;
    case TypeUint8:
        return JITUint8Array;
    case TypeUint8Clamped:
        return JITUint8ClampedArray;
    case TypeUint16:
        return JITUint16Array;
    case TypeUint32:
        return JITUint32Array;
    case TypeFloat32:
        return JITFloat32Array;
    case TypeFloat64:
        return JITFloat64Array;
    default:
        CRASH();
        return JITContiguous;
    }
}

inline bool jitArrayModePermitsPut(JITArrayMode mode)
{
    switch (mode) {
    case JITDirectArguments:
    case JITScopedArguments:
        // We could support put_by_val on these at some point, but it's just not that profitable
        // at the moment.
        return false;
    default:
        return true;
    }
}

inline bool jitArrayModePermitsPutDirect(JITArrayMode mode)
{
    // We don't allow typed array putDirect here since putDirect has
    // defineOwnProperty({configurable: true, writable:true, enumerable:true})
    // semantics. Typed array indexed properties are non-configurable by
    // default, so we can't simply store to a typed array for putDirect.
    //
    // We could model putDirect on ScopedArguments and DirectArguments, but we
    // haven't found any performance incentive to do it yet.
    switch (mode) {
    case JITInt32:
    case JITDouble:
    case JITContiguous:
    case JITArrayStorage:
        return true;
    default:
        return false;
    }
}

inline TypedArrayType typedArrayTypeForJITArrayMode(JITArrayMode mode)
{
    switch (mode) {
    case JITInt8Array:
        return TypeInt8;
    case JITInt16Array:
        return TypeInt16;
    case JITInt32Array:
        return TypeInt32;
    case JITUint8Array:
        return TypeUint8;
    case JITUint8ClampedArray:
        return TypeUint8Clamped;
    case JITUint16Array:
        return TypeUint16;
    case JITUint32Array:
        return TypeUint32;
    case JITFloat32Array:
        return TypeFloat32;
    case JITFloat64Array:
        return TypeFloat64;
    default:
        CRASH();
        return NotTypedArray;
    }
}

inline JITArrayMode jitArrayModeForStructure(Structure* structure)
{
    if (isOptimizableIndexingType(structure->indexingType()))
        return jitArrayModeForIndexingType(structure->indexingType());
    
    if (hasOptimizableIndexingForJSType(structure->typeInfo().type()))
        return jitArrayModeForJSType(structure->typeInfo().type());
    
    ASSERT(hasOptimizableIndexingForClassInfo(structure->classInfo()));
    return jitArrayModeForClassInfo(structure->classInfo());
}

struct ByValInfo {
    ByValInfo() { }

    ByValInfo(BytecodeIndex bytecodeIndex, CodeLocationJump<JSInternalPtrTag> notIndexJump, CodeLocationJump<JSInternalPtrTag> badTypeJump, CodeLocationLabel<ExceptionHandlerPtrTag> exceptionHandler, JITArrayMode arrayMode, ArrayProfile* arrayProfile, CodeLocationLabel<JSInternalPtrTag> badTypeDoneTarget, CodeLocationLabel<JSInternalPtrTag> badTypeNextHotPathTarget, CodeLocationLabel<JSInternalPtrTag> slowPathTarget)
        : notIndexJump(notIndexJump)
        , badTypeJump(badTypeJump)
        , exceptionHandler(exceptionHandler)
        , badTypeDoneTarget(badTypeDoneTarget)
        , badTypeNextHotPathTarget(badTypeNextHotPathTarget)
        , slowPathTarget(slowPathTarget)
        , arrayProfile(arrayProfile)
        , bytecodeIndex(bytecodeIndex)
        , slowPathCount(0)
        , stubInfo(nullptr)
        , arrayMode(arrayMode)
        , tookSlowPath(false)
        , seen(false)
    {
    }

    CodeLocationJump<JSInternalPtrTag> notIndexJump;
    CodeLocationJump<JSInternalPtrTag> badTypeJump;
    CodeLocationLabel<ExceptionHandlerPtrTag> exceptionHandler;
    CodeLocationLabel<JSInternalPtrTag> badTypeDoneTarget;
    CodeLocationLabel<JSInternalPtrTag> badTypeNextHotPathTarget;
    CodeLocationLabel<JSInternalPtrTag> slowPathTarget;
    ArrayProfile* arrayProfile;
    BytecodeIndex bytecodeIndex;
    unsigned slowPathCount;
    RefPtr<JITStubRoutine> stubRoutine;
    Identifier cachedId;
    WriteBarrier<Symbol> cachedSymbol;
    StructureStubInfo* stubInfo;
    JITArrayMode arrayMode; // The array mode that was baked into the inline JIT code.
    bool tookSlowPath : 1;
    bool seen : 1;
};

inline BytecodeIndex getByValInfoBytecodeIndex(ByValInfo* info)
{
    return info->bytecodeIndex;
}

#endif // ENABLE(JIT)

} // namespace JSC
