/*
 * 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 numberOfBytecodesWithMetadata = static_cast<OpcodeID>(NUMBER_OF_BYTECODE_WITH_METADATA);
    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;
};

struct WasmOpcodeTraits {
    using OpcodeID = WasmOpcodeID;
    static constexpr OpcodeID numberOfBytecodesWithMetadata = static_cast<OpcodeID>(NUMBER_OF_WASM_WITH_METADATA);
    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;
};


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<Width>::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()];
    }

    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>
    bool hasMetadata() const
    {
        return opcodeID<Traits>() < Traits::numberOfBytecodesWithMetadata;
    }

    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>();
        auto padding = sizeShiftAmount ? 1 : 0;
        auto size = 1 << sizeShiftAmount;
        return Traits::opcodeLengths[opcodeID<Traits>()] * size + padding;
    }

    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, 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>*>(bitwise_cast<uintptr_t>(this) + 1);
    }

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

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

struct Instruction : public BaseInstruction<OpcodeID> {
};

struct WasmInstance : public BaseInstruction<WasmOpcodeID> {
};

} // namespace JSC
