/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "ecmascript/message_string.h"


namespace panda::ecmascript {
// NOLINTNEXTLINE(fuchsia-statically-constructed-objects)
static std::array<std::string, MessageString::MAX_MESSAGE_COUNT> g_messageString = {
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define DEF_COMMON_MESSAGE(name, string) (string),
    COMMON_MESSAGE_STRING_LIST(DEF_COMMON_MESSAGE)
#undef DEF_COMMON_MESSAGE
#define DEF_ASM_INTERPRETER_STUB_MESSAGE(name) #name,
    ASM_INTERPRETER_BC_STUB_LIST(DEF_ASM_INTERPRETER_STUB_MESSAGE, DEF_ASM_INTERPRETER_STUB_MESSAGE)
    ASM_INTERPRETER_SECOND_BC_STUB_ID_LIST(DEF_ASM_INTERPRETER_STUB_MESSAGE)
    ASM_INTERPRETER_BC_HELPER_STUB_LIST(DEF_ASM_INTERPRETER_STUB_MESSAGE)
#if ECMASCRIPT_ENABLE_INTERPRETER_PGO_STUBS
#define DEF_ASM_INTERPRETER_STUB_MESSAGE_DYN(name, ...) DEF_ASM_INTERPRETER_STUB_MESSAGE(name)
    ASM_INTERPRETER_BC_PROFILER_STUB_LIST(DEF_ASM_INTERPRETER_STUB_MESSAGE_DYN)
    ASM_INTERPRETER_BC_JIT_PROFILER_STUB_LIST(DEF_ASM_INTERPRETER_STUB_MESSAGE_DYN)
#undef DEF_ASM_INTERPRETER_STUB_MESSAGE_DYN
#endif
#define DEF_STW_COPY_STUB_MESSAGE(name) #name"StwCopy",
    ASM_INTERPRETER_BC_STW_COPY_STUB_LIST(DEF_STW_COPY_STUB_MESSAGE)
    COMMON_STUB_LIST(DEF_ASM_INTERPRETER_STUB_MESSAGE)
    COMMON_STW_COPY_STUB_LIST(DEF_STW_COPY_STUB_MESSAGE)
#undef DEF_STW_COPY_STUB_MESSAGE
#define DEF_BUILTINS_STUB_MESSAGE(name) "Builtins Stub "#name,
#define DEF_BUILTINS_STUB_MESSAGE_DYN(name, type, ...) "Builtins Stub "#type#name,
    BUILTINS_STUB_LIST(DEF_BUILTINS_STUB_MESSAGE, DEF_BUILTINS_STUB_MESSAGE_DYN, DEF_BUILTINS_STUB_MESSAGE)
#undef DEF_BUILTINS_STUB_MESSAGE_DYN
#undef DEF_BUILTINS_STUB_MESSAGE
#define DEF_BUILTINS_STW_COPY_STUB_MESSAGE(name) "Builtins Stub "#name"StwCopy",
#define DEF_BUILTINS_STW_COPY_STUB_MESSAGE_DYN(name, type, ...) "Builtins Stub "#type#name"StwCopy",
    BUILTINS_STW_COPY_STUB_LIST(DEF_BUILTINS_STW_COPY_STUB_MESSAGE, DEF_BUILTINS_STW_COPY_STUB_MESSAGE_DYN, \
        DEF_BUILTINS_STW_COPY_STUB_MESSAGE)
#undef DEF_BUILTINS_STW_COPY_STUB_MESSAGE_DYN
#undef DEF_BUILTINS_STW_COPY_STUB_MESSAGE
    BASELINE_STUB_ID_LIST(DEF_ASM_INTERPRETER_STUB_MESSAGE)
    RUNTIME_ASM_STUB_LIST(DEF_ASM_INTERPRETER_STUB_MESSAGE)
#undef DEF_ASM_INTERPRETER_STUB_MESSAGE
#define DEF_ISHEAPOBJECT_MESSAGE(name) #name"DebugCheck IR:line:%d",
    DEBUG_CHECK_MESSAGE_STRING_LIST(DEF_ISHEAPOBJECT_MESSAGE)
#undef DEF_ISHEAPOBJECT_MESSAGE
};

#define ASSERT_BC_STUB_MESSAGE_ALIGN(name)                                                  \
    static_assert(GET_MESSAGE_STRING_ID(name) - GET_MESSAGE_STRING_ID(HandleLdundefined) == \
        static_cast<int>(kungfu::BytecodeStubCSigns::ID_##name));
ASM_INTERPRETER_BC_STUB_LIST(ASSERT_BC_STUB_MESSAGE_ALIGN, ASSERT_BC_STUB_MESSAGE_ALIGN)
ASM_INTERPRETER_SECOND_BC_STUB_ID_LIST(ASSERT_BC_STUB_MESSAGE_ALIGN)
ASM_INTERPRETER_BC_HELPER_STUB_LIST(ASSERT_BC_STUB_MESSAGE_ALIGN)
#if ECMASCRIPT_ENABLE_INTERPRETER_PGO_STUBS
#define ASSERT_BC_STUB_MESSAGE_ALIGN_DYN(name, ...) ASSERT_BC_STUB_MESSAGE_ALIGN(name)
ASM_INTERPRETER_BC_PROFILER_STUB_LIST(ASSERT_BC_STUB_MESSAGE_ALIGN_DYN)
#if ECMASCRIPT_ENABLE_INTERPRETER_JIT_STUBS
ASM_INTERPRETER_BC_JIT_PROFILER_STUB_LIST(ASSERT_BC_STUB_MESSAGE_ALIGN_DYN)
#endif
#undef ASSERT_BC_STUB_MESSAGE_ALIGN_DYN
#endif
#define ASSERT_BC_STW_COPY_STUB_MESSAGE_ALIGN(name) ASSERT_BC_STUB_MESSAGE_ALIGN(name##StwCopy)
ASM_INTERPRETER_BC_STW_COPY_STUB_LIST(ASSERT_BC_STW_COPY_STUB_MESSAGE_ALIGN)
#undef ASSERT_BC_STW_COPY_STUB_MESSAGE_ALIGN
#undef ASSERT_BC_STUB_MESSAGE_ALIGN

#define ASSERT_COMMON_STUB_MESSAGE_ALIGN(name)                                \
    static_assert(GET_MESSAGE_STRING_ID(name) - GET_MESSAGE_STRING_ID(Add) == \
        static_cast<int>(kungfu::CommonStubCSigns::name));
COMMON_STUB_LIST(ASSERT_COMMON_STUB_MESSAGE_ALIGN)
#define ASSERT_COMMON_STW_COPY_STUB_MESSAGE_ALIGN(name) ASSERT_COMMON_STUB_MESSAGE_ALIGN(name##StwCopy)
COMMON_STW_COPY_STUB_LIST(ASSERT_COMMON_STW_COPY_STUB_MESSAGE_ALIGN)
#undef ASSERT_COMMON_STW_COPY_STUB_MESSAGE_ALIGN
#undef ASSERT_COMMON_STUB_MESSAGE_ALIGN

#define ASSERT_BUILTINS_STUB_MESSAGE_ALIGN(name)                                           \
    static_assert(GET_MESSAGE_STRING_ID(name) - GET_MESSAGE_STRING_ID(StringCharAt) + 1 == \
        static_cast<int>(kungfu::BuiltinsStubCSigns::ID_##name));
#define ASSERT_BUILTINS_STUB_MESSAGE_ALIGN_DYN(name, type, ...) ASSERT_BUILTINS_STUB_MESSAGE_ALIGN(type##name)
BUILTINS_STUB_LIST(ASSERT_BUILTINS_STUB_MESSAGE_ALIGN, ASSERT_BUILTINS_STUB_MESSAGE_ALIGN_DYN, \
    ASSERT_BUILTINS_STUB_MESSAGE_ALIGN)
#undef ASSERT_BUILTINS_STUB_MESSAGE_ALIGN_DYN
#define ASSERT_BUILTINS_STW_COPY_STUB_MESSAGE_ALIGN(name) ASSERT_BUILTINS_STUB_MESSAGE_ALIGN(name##StwCopy)
#define ASSERT_BUILTINS_STW_COPY_STUB_MESSAGE_ALIGN_DYN(name, type, ...) \
    ASSERT_BUILTINS_STUB_MESSAGE_ALIGN(type##name##StwCopy)
BUILTINS_STW_COPY_STUB_LIST(ASSERT_BUILTINS_STW_COPY_STUB_MESSAGE_ALIGN, \
    ASSERT_BUILTINS_STW_COPY_STUB_MESSAGE_ALIGN_DYN, ASSERT_BUILTINS_STW_COPY_STUB_MESSAGE_ALIGN)
#undef ASSERT_BUILTINS_STW_COPY_STUB_MESSAGE_ALIGN_DYN
#undef ASSERT_BUILTINS_STW_COPY_STUB_MESSAGE_ALIGN
#undef ASSERT_BUILTINS_STUB_MESSAGE_ALIGN

#define ASSERT_BASELINE_STUB_MESSAGE_ALIGN(name)                                                            \
    static_assert(GET_MESSAGE_STRING_ID(name) - GET_MESSAGE_STRING_ID(BaselineTryLdGLobalByNameImm8ID16) == \
        static_cast<int>(kungfu::BaselineStubCSigns::name));
BASELINE_STUB_ID_LIST(ASSERT_BASELINE_STUB_MESSAGE_ALIGN)
#undef ASSERT_BASELINE_STUB_MESSAGE_ALIGN

#define ASSERT_RT_STUB_MESSAGE_ALIGN(name)                                            \
    static_assert(GET_MESSAGE_STRING_ID(name) - GET_MESSAGE_STRING_ID(CallRuntime) == \
        static_cast<int>(kungfu::RuntimeStubCSigns::ID_##name));
RUNTIME_ASM_STUB_LIST(ASSERT_RT_STUB_MESSAGE_ALIGN)
#undef ASSERT_RT_STUB_MESSAGE_ALIGN

void MessageString::CheckStubNameInfo()
{
#define CHECK_STUB_MESSAGE_ALIGN(name) \
    ASSERT(g_messageString[GET_MESSAGE_STRING_ID(name)] == #name);
    ASM_INTERPRETER_BC_STUB_LIST(CHECK_STUB_MESSAGE_ALIGN, CHECK_STUB_MESSAGE_ALIGN)
    ASM_INTERPRETER_SECOND_BC_STUB_ID_LIST(CHECK_STUB_MESSAGE_ALIGN)
    ASM_INTERPRETER_BC_HELPER_STUB_LIST(CHECK_STUB_MESSAGE_ALIGN)
#if ECMASCRIPT_ENABLE_INTERPRETER_PGO_STUBS
#define CHECK_STUB_MESSAGE_ALIGN_DYN(name, ...) CHECK_STUB_MESSAGE_ALIGN(name)
    ASM_INTERPRETER_BC_PROFILER_STUB_LIST(CHECK_STUB_MESSAGE_ALIGN_DYN)
#if ECMASCRIPT_ENABLE_INTERPRETER_JIT_STUBS
    ASM_INTERPRETER_BC_JIT_PROFILER_STUB_LIST(CHECK_STUB_MESSAGE_ALIGN_DYN)
#endif
#undef CHECK_STUB_MESSAGE_ALIGN_DYN
#endif
#define CHECK_STW_COPY_STUB_MESSAGE_ALIGN(name) \
    ASSERT(g_messageString[GET_MESSAGE_STRING_ID(name##StwCopy)] == #name"StwCopy");
    ASM_INTERPRETER_BC_STW_COPY_STUB_LIST(CHECK_STW_COPY_STUB_MESSAGE_ALIGN)
    COMMON_STUB_LIST(CHECK_STUB_MESSAGE_ALIGN)
    COMMON_STW_COPY_STUB_LIST(CHECK_STW_COPY_STUB_MESSAGE_ALIGN)
#undef CHECK_STW_COPY_STUB_MESSAGE_ALIGN
#define CHECK_BUILTINS_STUB_MESSAGE_ALIGN(name) \
    ASSERT(g_messageString[GET_MESSAGE_STRING_ID(name)] == "Builtins Stub "#name);
#define CHECK_BUILTINS_STUB_MESSAGE_ALIGN_DYN(name, type, ...) \
    ASSERT(g_messageString[GET_MESSAGE_STRING_ID(type##name)] == "Builtins Stub "#type#name);
    BUILTINS_STUB_LIST(CHECK_BUILTINS_STUB_MESSAGE_ALIGN, CHECK_BUILTINS_STUB_MESSAGE_ALIGN_DYN, \
        CHECK_BUILTINS_STUB_MESSAGE_ALIGN)
#undef CHECK_BUILTINS_STUB_MESSAGE_ALIGN_DYN
#undef CHECK_BUILTINS_STUB_MESSAGE_ALIGN
#define CHECK_BUILTINS_STW_COPY_STUB_MESSAGE_ALIGN(name) \
    ASSERT(g_messageString[GET_MESSAGE_STRING_ID(name##StwCopy)] == "Builtins Stub "#name"StwCopy");
#define CHECK_BUILTINS_STW_COPY_STUB_MESSAGE_ALIGN_DYN(name, type, ...) \
    ASSERT(g_messageString[GET_MESSAGE_STRING_ID(type##name##StwCopy)] == "Builtins Stub "#type#name"StwCopy");
    BUILTINS_STW_COPY_STUB_LIST(CHECK_BUILTINS_STW_COPY_STUB_MESSAGE_ALIGN, \
        CHECK_BUILTINS_STW_COPY_STUB_MESSAGE_ALIGN_DYN, CHECK_BUILTINS_STW_COPY_STUB_MESSAGE_ALIGN)
#undef CHECK_BUILTINS_STW_COPY_STUB_MESSAGE_ALIGN_DYN
#undef CHECK_BUILTINS_STW_COPY_STUB_MESSAGE_ALIGN
    BASELINE_STUB_ID_LIST(CHECK_STUB_MESSAGE_ALIGN)
    RUNTIME_ASM_STUB_LIST(CHECK_STUB_MESSAGE_ALIGN)
#undef CHECK_STUB_MESSAGE_ALIGN
}

const std::string& MessageString::GetMessageString(int id)
{
    ASSERT(id < MessageString::MAX_MESSAGE_COUNT);
    return g_messageString[id];
}
}  // namespace panda::ecmascript