/*
 * Copyright (C) 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. AND ITS CONTRIBUTORS ``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 ITS 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 "Opcode.h"
#include "OpcodeSize.h"

namespace JSC {

struct JSOpcodeTraits {
    using OpcodeID = ::JSC::OpcodeID;
    static constexpr OpcodeID numberOfBytecodesWithCheckpoints = static_cast<OpcodeID>(NUMBER_OF_BYTECODE_WITH_CHECKPOINTS);
    static constexpr OpcodeID numberOfBytecodesWithMetadata = static_cast<OpcodeID>(NUMBER_OF_BYTECODE_WITH_METADATA);
    static_assert(numberOfBytecodesWithCheckpoints <= numberOfBytecodesWithMetadata);
    static constexpr OpcodeID wide16 = op_wide16;
    static constexpr OpcodeID wide32 = op_wide32;
    static constexpr const unsigned* opcodeLengths = ::JSC::opcodeLengths;
    static constexpr const char* const* opcodeNames = ::JSC::opcodeNames;
    static constexpr auto checkpointCountTable = bytecodeCheckpointCountTable;
};

struct WasmOpcodeTraits {
    using OpcodeID = WasmOpcodeID;
    static constexpr OpcodeID numberOfBytecodesWithCheckpoints = static_cast<OpcodeID>(NUMBER_OF_WASM_WITH_CHECKPOINTS);
    static constexpr OpcodeID numberOfBytecodesWithMetadata = static_cast<OpcodeID>(NUMBER_OF_WASM_WITH_METADATA);
    static_assert(numberOfBytecodesWithCheckpoints <= numberOfBytecodesWithMetadata);
    static constexpr OpcodeID wide16 = wasm_wide16;
    static constexpr OpcodeID wide32 = wasm_wide32;
    static constexpr const unsigned* opcodeLengths = wasmOpcodeLengths;
    static constexpr const char* const* opcodeNames = wasmOpcodeNames;
    static constexpr auto checkpointCountTable = wasmCheckpointCountTable;
};


template<typename Opcode>
struct BaseInstruction {

    struct Metadata { };

protected:
    BaseInstruction()
    { }

private:
    template<OpcodeSize Width>
    class Impl {
    public:
        template<typename Traits = JSOpcodeTraits>
        typename Traits::OpcodeID opcodeID() const { return static_cast<typename Traits::OpcodeID>(m_opcode); }

    private:
        typename TypeBySize<OpcodeSize::Narrow>::unsignedType m_opcode;
    };

public:
    template<typename Traits = JSOpcodeTraits>
    typename Traits::OpcodeID opcodeID() const
    {
        if (isWide32<Traits>())
            return wide32<Traits>()->template opcodeID<Traits>();
        if (isWide16<Traits>())
            return wide16<Traits>()->template opcodeID<Traits>();
        return narrow()->template opcodeID<Traits>();
    }

    template<typename Traits = JSOpcodeTraits>
    const char* name() const
    {
        return Traits::opcodeNames[opcodeID<Traits>()];
    }

    template<typename Traits = JSOpcodeTraits>
    bool isWide16() const
    {
        return narrow()->template opcodeID<Traits>() == Traits::wide16;
    }

    template<typename Traits = JSOpcodeTraits>
    bool isWide32() const
    {
        return narrow()->template opcodeID<Traits>() == Traits::wide32;
    }

    template<typename Traits = JSOpcodeTraits>
    OpcodeSize width() const
    {
        if (isWide32<Traits>())
            return OpcodeSize::Wide32;
        return isWide16<Traits>() ? OpcodeSize::Wide16 : OpcodeSize::Narrow;
    }

    template<typename Traits = JSOpcodeTraits>
    bool hasMetadata() const
    {
        return opcodeID<Traits>() < Traits::numberOfBytecodesWithMetadata;
    }

    template<typename Traits = JSOpcodeTraits>
    bool hasCheckpoints() const
    {
        return opcodeID<Traits>() < Traits::numberOfBytecodesWithCheckpoints;
    }

    template<typename Traits = JSOpcodeTraits>
    unsigned numberOfCheckpoints() const
    {
        if (!hasCheckpoints<Traits>())
            return 1;
        return Traits::checkpointCountTable[opcodeID<Traits>()];
    }

    template<typename Traits = JSOpcodeTraits>
    int sizeShiftAmount() const
    {
        if (isWide32<Traits>())
            return 2;
        if (isWide16<Traits>())
            return 1;
        return 0;
    }

    template<typename Traits = JSOpcodeTraits>
    size_t size() const
    {
        auto sizeShiftAmount = this->sizeShiftAmount<Traits>();
        size_t prefixSize = sizeShiftAmount ? 1 : 0;
        size_t operandSize = static_cast<size_t>(1) << sizeShiftAmount;
        size_t sizeOfBytecode = 1;
        return sizeOfBytecode + (Traits::opcodeLengths[opcodeID<Traits>()] - 1) * operandSize + prefixSize;
    }

    template<class T, typename Traits = JSOpcodeTraits>
    bool is() const
    {
        return opcodeID<Traits>() == T::opcodeID;
    }

    template<class T, typename Traits = JSOpcodeTraits>
    T as() const
    {
        ASSERT((is<T, Traits>()));
        return T::decode(reinterpret_cast<const uint8_t*>(this));
    }

    template<class T, OpcodeSize width, typename Traits = JSOpcodeTraits>
    T asKnownWidth() const
    {
        ASSERT((is<T, Traits>()));
        return T(reinterpret_cast_ptr<const typename TypeBySize<width>::unsignedType*>(this + (width == OpcodeSize::Narrow ? 1 : 2)));
    }

    template<class T, typename Traits = JSOpcodeTraits>
    T* cast()
    {
        ASSERT((is<T, Traits>()));
        return bitwise_cast<T*>(this);
    }

    template<class T, typename Traits = JSOpcodeTraits>
    const T* cast() const
    {
        ASSERT((is<T, Traits>()));
        return reinterpret_cast<const T*>(this);
    }

    const Impl<OpcodeSize::Narrow>* narrow() const
    {
        return reinterpret_cast<const Impl<OpcodeSize::Narrow>*>(this);
    }

    template<typename Traits = JSOpcodeTraits>
    const Impl<OpcodeSize::Wide16>* wide16() const
    {

        ASSERT(isWide16<Traits>());
        return reinterpret_cast<const Impl<OpcodeSize::Wide16>*>(this + 1);
    }

    template<typename Traits = JSOpcodeTraits>
    const Impl<OpcodeSize::Wide32>* wide32() const
    {

        ASSERT(isWide32<Traits>());
        return reinterpret_cast<const Impl<OpcodeSize::Wide32>*>(this + 1);
    }
};

struct Instruction : public BaseInstruction<OpcodeID> {
};
static_assert(sizeof(Instruction) == 1, "So pointer math is the same as byte math");

struct WasmInstance : public BaseInstruction<WasmOpcodeID> {
};
static_assert(sizeof(WasmInstance) == 1, "So pointer math is the same as byte math");

} // namespace JSC
