arkcompiler_ets_runtime/ecmascript/interpreter/interpreter-inl.h
hecunmao 61b5c2f5fb An exception was generated when throwing an exception. Procedure
issue:https://gitee.com/open_harmony/dashboard?issue_id=I9RPS3
Signed-off-by: hecunmao <hecunmao@huawei.com>

Change-Id: I34067353d54e2a670bf96fa0f4897b100505dbbf
2024-06-03 22:19:49 +08:00

663 lines
34 KiB
C++

/*
* 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.
*/
#ifndef ECMASCRIPT_INTERPRETER_INTERPRETER_INL_H
#define ECMASCRIPT_INTERPRETER_INTERPRETER_INL_H
#include "ecmascript/debugger/js_debugger_manager.h"
#include "ecmascript/ecma_context.h"
#include "ecmascript/ecma_string.h"
#include "ecmascript/ecma_vm.h"
#include "ecmascript/global_env.h"
#include "ecmascript/ic/ic_runtime_stub-inl.h"
#include "ecmascript/interpreter/fast_runtime_stub-inl.h"
#include "ecmascript/interpreter/interpreter.h"
#include "ecmascript/interpreter/interpreter_assembly.h"
#include "ecmascript/interpreter/frame_handler.h"
#include "ecmascript/interpreter/slow_runtime_stub.h"
#include "ecmascript/jspandafile/literal_data_extractor.h"
#include "ecmascript/jspandafile/program_object.h"
#include "ecmascript/js_async_generator_object.h"
#include "ecmascript/js_generator_object.h"
#include "ecmascript/js_tagged_value.h"
#include "ecmascript/jit/jit_task.h"
#include "ecmascript/mem/concurrent_marker.h"
#include "ecmascript/module/js_module_manager.h"
#include "ecmascript/module/js_module_source_text.h"
#include "ecmascript/runtime_call_id.h"
#include "ecmascript/stubs/runtime_stubs.h"
#include "ecmascript/sendable_env.h"
#include "ecmascript/template_string.h"
#include "ecmascript/checkpoint/thread_state_transition.h"
#if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
#include "ecmascript/dfx/cpu_profiler/cpu_profiler.h"
#endif
namespace panda::ecmascript {
using CommonStubCSigns = kungfu::CommonStubCSigns;
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wvoid-ptr-dereference"
#pragma clang diagnostic ignored "-Wgnu-label-as-value"
#elif defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
#if ECMASCRIPT_ENABLE_INTERPRETER_LOG
#define HANDLE_OPCODE(opcode) \
HANDLE_##opcode: \
{ \
RuntimeStubs::DebugPrintInstruction(thread->GetGlueAddr(), pc); \
}
#else
#define HANDLE_OPCODE(opcode) \
HANDLE_##opcode:
#endif
#define NOPRINT_HANDLE_OPCODE(opcode) \
HANDLE_##opcode:
#define LOG_INST() false && LOG_INTERPRETER(DEBUG)
#define DEBUG_HANDLE_OPCODE(opcode) \
DEBUG_HANDLE_##opcode:
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define ADVANCE_PC(offset) \
pc += (offset); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic, cppcoreguidelines-macro-usage)
#define GOTO_NEXT() // NOLINT(clang-diagnostic-gnu-label-as-value, cppcoreguidelines-macro-usage)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define DISPATCH(curOpcode) \
do { \
ADVANCE_PC(BytecodeInstruction::Size(EcmaOpcode::curOpcode)) \
opcode = READ_INST_OP(); goto *dispatchTable[opcode]; \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define DISPATCH_OFFSET(offset) \
do { \
ADVANCE_PC(offset) \
opcode = READ_INST_OP(); goto *dispatchTable[opcode]; \
} while (false)
#define DISPATCH_THROW() \
do { \
opcode = *(pc + 1); \
goto *throwDispatchTable[opcode]; \
} while (false)
#define DISPATCH_WIDE() \
do { \
opcode = *(pc + 1); \
goto *wideDispatchTable[opcode]; \
} while (false)
#define DISPATCH_DEPRECATED() \
do { \
opcode = *(pc + 1); \
goto *deprecatedDispatchTable[opcode]; \
} while (false)
#define DISPATCH_CALLRUNTIME() \
do { \
opcode = *(pc + 1); \
goto *callRuntimeDispatchTable[opcode]; \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define GET_FRAME(CurrentSp) \
(reinterpret_cast<InterpretedFrame *>(CurrentSp) - 1) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define GET_ENTRY_FRAME(sp) \
(reinterpret_cast<InterpretedEntryFrame *>(sp) - 1) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
#define GET_BUILTIN_FRAME(sp) \
(reinterpret_cast<InterpretedBuiltinFrame *>(sp) - 1) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define SAVE_PC() (GET_FRAME(sp)->pc = pc) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define SAVE_ACC() (GET_FRAME(sp)->acc = acc) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define RESTORE_ACC() (acc = GET_FRAME(sp)->acc) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define GET_VREG(idx) (sp[idx]) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define GET_VREG_VALUE(idx) (JSTaggedValue(sp[idx])) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define SET_VREG(idx, val) (sp[idx] = (val)); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
#define GET_ACC() (acc) // NOLINT(cppcoreguidelines-macro-usage)
#define SET_ACC(val) (acc = val) // NOLINT(cppcoreguidelines-macro-usage)
#define GET_METHOD_FROM_CACHE(index) \
ConstantPool::GetMethodFromCache(thread, constpool, index)
#define GET_STR_FROM_CACHE(index) \
ConstantPool::GetStringFromCache(thread, constpool, index)
#define GET_LITERA_FROM_CACHE(index, type, module) \
ConstantPool::GetLiteralFromCache<type>(thread, constpool, index, module)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define INTERPRETER_GOTO_EXCEPTION_HANDLER() \
do { \
SAVE_PC(); \
goto *dispatchTable[EXCEPTION_OPCODE]; \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define INTERPRETER_HANDLE_RETURN() \
do { \
size_t jumpSize = GetJumpSizeAfterCall(pc); \
DISPATCH_OFFSET(jumpSize); \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CHECK_SWITCH_TO_DEBUGGER_TABLE() \
if (ecmaVm->GetJsDebuggerManager()->IsDebugMode()) { \
dispatchTable = debugDispatchTable.data(); \
}
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define REAL_GOTO_DISPATCH_OPCODE(opcode) \
do { \
ASSERT(static_cast<uint16_t>(opcode) <= 0xff); \
goto *instDispatchTable[static_cast<uint8_t>(opcode)]; \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define REAL_GOTO_EXCEPTION_HANDLER() \
do { \
SAVE_PC(); \
goto *instDispatchTable[EXCEPTION_OPCODE]; \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define INTERPRETER_RETURN_IF_ABRUPT(result) \
do { \
if (result.IsException()) { \
INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
} \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define HANDLE_EXCEPTION_IF_ABRUPT_COMPLETION(_thread) \
do { \
if (UNLIKELY((_thread)->HasPendingException())) { \
INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
} \
} while (false)
#define JUMP_IF_ENTRYFRAME_PENDING() \
do { \
if (thread->IsEntryFrameDroppedPending()) { \
thread->ResetEntryFrameDroppedState(); \
DROPFRAME_JUMP(); \
} \
} while (false)
#define DROPFRAME_JUMP() \
do { \
thread->ResetFrameDroppedState(); \
sp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame()); \
InterpretedFrame *state = GET_FRAME(sp); \
pc = state->pc; \
RESTORE_ACC(); \
DISPATCH_OFFSET(0); \
} while (false)
#define RESET_AND_JUMP_IF_DROPFRAME() \
do { \
if (thread->IsFrameDropped()) { \
if (thread->IsEntryFrameDroppedTrue()) { \
return; \
} \
DROPFRAME_JUMP(); \
} \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define NOTIFY_DEBUGGER_EVENT() \
do { \
JUMP_IF_ENTRYFRAME_PENDING(); \
SAVE_ACC(); \
SAVE_PC(); \
NotifyBytecodePcChanged(thread); \
RESET_AND_JUMP_IF_DROPFRAME(); \
RESTORE_ACC(); \
} while (false)
/*
* reasons of set acc with hole:
* 1. acc will become illegal when new error
* 2. debugger logic will save acc, so illegal acc will set to frame
* 3. when debugger trigger gc, will mark an invalid acc and crash
* 4. acc will set to exception later, so it can set to hole template
*/
#define NOTIFY_DEBUGGER_EXCEPTION_EVENT() \
do { \
SET_ACC(JSTaggedValue::Hole()); \
NOTIFY_DEBUGGER_EVENT(); \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define DEPRECATED_CALL_INITIALIZE() \
do { \
SAVE_PC(); \
thread->CheckSafepoint(); \
funcTagged = sp[startReg]; \
JSTaggedValue funcValue(funcTagged); \
if (!funcValue.IsCallable()) { \
{ \
[[maybe_unused]] EcmaHandleScope handleScope(thread); \
JSHandle<JSObject> error = factory->GetJSError( \
ErrorType::TYPE_ERROR, "is not callable", StackCheck::NO); \
thread->SetException(error.GetTaggedValue()); \
} \
INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
} \
funcObject = ECMAObject::Cast(funcValue.GetTaggedObject()); \
methodHandle.Update(JSTaggedValue(funcObject->GetCallTarget())); \
newSp = sp - InterpretedFrame::NumOfMembers(); \
} while (false)
#define CALL_INITIALIZE() \
do { \
SAVE_PC(); \
SAVE_ACC(); \
thread->CheckSafepoint(); \
RESTORE_ACC(); \
funcTagged = acc.GetRawData(); \
JSTaggedValue funcValue = acc; \
if (!funcValue.IsCallable()) { \
{ \
[[maybe_unused]] EcmaHandleScope handleScope(thread); \
JSHandle<JSObject> error = factory->GetJSError( \
ErrorType::TYPE_ERROR, "is not callable", StackCheck::NO); \
thread->SetException(error.GetTaggedValue()); \
} \
INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
} \
funcObject = ECMAObject::Cast(funcValue.GetTaggedObject()); \
methodHandle.Update(JSTaggedValue(funcObject->GetCallTarget())); \
newSp = sp - InterpretedFrame::NumOfMembers(); \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CALL_PUSH_UNDEFINED(n) \
do { \
for (int i = 0; i < (n); i++) { \
*(--newSp) = JSTaggedValue::VALUE_UNDEFINED; \
} \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CALL_PUSH_ARGS_0() \
do { \
/* do nothing when 0 arg */ \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define DEPRECATED_CALL_PUSH_ARGS_0() CALL_PUSH_ARGS_0()
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CALL_PUSH_ARGS_1() \
do { \
*(--newSp) = sp[a0]; \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define DEPRECATED_CALL_PUSH_ARGS_1() CALL_PUSH_ARGS_1()
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CALL_PUSH_ARGS_2() \
do { \
*(--newSp) = sp[a1]; \
CALL_PUSH_ARGS_1(); \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define DEPRECATED_CALL_PUSH_ARGS_2() CALL_PUSH_ARGS_2()
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CALL_PUSH_ARGS_3() \
do { \
*(--newSp) = sp[a2]; \
CALL_PUSH_ARGS_2(); \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define DEPRECATED_CALL_PUSH_ARGS_3() CALL_PUSH_ARGS_3()
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CALL_PUSH_ARGS_RANGE() \
do { \
if (UNLIKELY(thread->DoStackOverflowCheck(newSp - actualNumArgs))) { \
INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
} \
for (int i = actualNumArgs - 1; i >= 0; i--) { \
*(--newSp) = sp[startReg + static_cast<uint32_t>(i)]; \
} \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define DEPRECATED_CALL_PUSH_ARGS_RANGE() \
do { \
if (UNLIKELY(thread->DoStackOverflowCheck(newSp - actualNumArgs))) { \
INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
} \
for (int i = actualNumArgs; i > 0; i--) { \
*(--newSp) = sp[startReg + static_cast<uint32_t>(i)]; \
} \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CALL_PUSH_ARGS_THISRANGE() \
do { \
if (UNLIKELY(thread->DoStackOverflowCheck(newSp - actualNumArgs))) { \
INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
} \
/* 1: skip this */ \
for (int i = actualNumArgs; i > 0; i--) { \
*(--newSp) = sp[startReg + static_cast<uint32_t>(i)]; \
} \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define DEPRECATED_CALL_PUSH_ARGS_THISRANGE() \
do { \
if (UNLIKELY(thread->DoStackOverflowCheck(newSp - actualNumArgs))) { \
INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
} \
/* 1: skip this */ \
for (int i = actualNumArgs + 1; i > 1; i--) { \
*(--newSp) = sp[startReg + static_cast<uint32_t>(i)]; \
} \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CALL_PUSH_ARGS_0_NO_EXTRA() \
do { \
/* do nothing when 0 arg */ \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define DEPRECATED_CALL_PUSH_ARGS_0_NO_EXTRA() CALL_PUSH_ARGS_0_NO_EXTRA()
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CALL_PUSH_ARGS_1_NO_EXTRA() \
do { \
if (declaredNumArgs >= ActualNumArgsOfCall::CALLARG1) { \
*(--newSp) = sp[a0]; \
} \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define DEPRECATED_CALL_PUSH_ARGS_1_NO_EXTRA() CALL_PUSH_ARGS_1_NO_EXTRA()
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CALL_PUSH_ARGS_2_NO_EXTRA() \
do { \
if (declaredNumArgs >= ActualNumArgsOfCall::CALLARGS2) { \
*(--newSp) = sp[a1]; \
} \
DEPRECATED_CALL_PUSH_ARGS_1_NO_EXTRA(); \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define DEPRECATED_CALL_PUSH_ARGS_2_NO_EXTRA() CALL_PUSH_ARGS_2_NO_EXTRA()
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CALL_PUSH_ARGS_3_NO_EXTRA() \
do { \
if (declaredNumArgs >= ActualNumArgsOfCall::CALLARGS3) { \
*(--newSp) = sp[a2]; \
} \
DEPRECATED_CALL_PUSH_ARGS_2_NO_EXTRA(); \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define DEPRECATED_CALL_PUSH_ARGS_3_NO_EXTRA() CALL_PUSH_ARGS_3_NO_EXTRA()
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CALL_PUSH_ARGS_RANGE_NO_EXTRA() \
do { \
int num = std::min(actualNumArgs, declaredNumArgs); \
if (UNLIKELY(thread->DoStackOverflowCheck(newSp - num))) { \
INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
} \
for (int i = num - 1; i >= 0; i--) { \
*(--newSp) = sp[startReg + static_cast<uint32_t>(i)]; \
} \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define DEPRECATED_CALL_PUSH_ARGS_RANGE_NO_EXTRA() \
do { \
int num = std::min(actualNumArgs, declaredNumArgs); \
if (UNLIKELY(thread->DoStackOverflowCheck(newSp - num))) { \
INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
} \
for (int i = num; i > 0; i--) { \
*(--newSp) = sp[startReg + static_cast<uint32_t>(i)]; \
} \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CALL_PUSH_ARGS_THISRANGE_NO_EXTRA() \
do { \
int num = std::min(actualNumArgs, declaredNumArgs); \
if (UNLIKELY(thread->DoStackOverflowCheck(newSp - num))) { \
INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
} \
/* 1: skip this */ \
for (int i = num; i > 0; i--) { \
*(--newSp) = sp[startReg + static_cast<uint32_t>(i)]; \
} \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define DEPRECATED_CALL_PUSH_ARGS_THISRANGE_NO_EXTRA() \
do { \
int num = std::min(actualNumArgs, declaredNumArgs); \
if (UNLIKELY(thread->DoStackOverflowCheck(newSp - num))) { \
INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
} \
/* 1: skip this */ \
for (int i = num + 1; i > 1; i--) { \
*(--newSp) = sp[startReg + static_cast<uint32_t>(i)]; \
} \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CALL_PUSH_ARGS(ARG_TYPE) \
do { \
if (methodHandle->IsNativeWithCallField()) { \
/* native, just push all args directly */ \
CALL_PUSH_ARGS_##ARG_TYPE(); \
goto setVregsAndFrameNative; \
} \
int32_t declaredNumArgs = \
static_cast<int32_t>(methodHandle->GetNumArgsWithCallField()); \
if (actualNumArgs == declaredNumArgs) { \
/* fast path, just push all args directly */ \
CALL_PUSH_ARGS_##ARG_TYPE(); \
goto setVregsAndFrameNotNative; \
} \
/* slow path */ \
if (!methodHandle->HaveExtraWithCallField()) { \
/* push length = declaredNumArgs, may push undefined */ \
CALL_PUSH_UNDEFINED(declaredNumArgs - actualNumArgs); \
CALL_PUSH_ARGS_##ARG_TYPE##_NO_EXTRA(); \
} else { \
/* push actualNumArgs in the end, then all args, may push undefined */ \
*(--newSp) = JSTaggedValue(actualNumArgs).GetRawData(); \
CALL_PUSH_UNDEFINED(declaredNumArgs - actualNumArgs); \
CALL_PUSH_ARGS_##ARG_TYPE(); \
} \
goto setVregsAndFrameNotNative; \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define DEPRECATED_CALL_PUSH_ARGS(ARG_TYPE) \
do { \
if (methodHandle->IsNativeWithCallField()) { \
/* native, just push all args directly */ \
DEPRECATED_CALL_PUSH_ARGS_##ARG_TYPE(); \
goto deprecatedSetVregsAndFrameNative; \
} \
int32_t declaredNumArgs = \
static_cast<int32_t>(methodHandle->GetNumArgsWithCallField()); \
if (actualNumArgs == declaredNumArgs) { \
/* fast path, just push all args directly */ \
DEPRECATED_CALL_PUSH_ARGS_##ARG_TYPE(); \
goto deprecatedSetVregsAndFrameNotNative; \
} \
/* slow path */ \
if (!methodHandle->HaveExtraWithCallField()) { \
/* push length = declaredNumArgs, may push undefined */ \
CALL_PUSH_UNDEFINED(declaredNumArgs - actualNumArgs); \
DEPRECATED_CALL_PUSH_ARGS_##ARG_TYPE##_NO_EXTRA(); \
} else { \
/* push actualNumArgs in the end, then all args, may push undefined */ \
*(--newSp) = JSTaggedValue(actualNumArgs).GetRawData(); \
CALL_PUSH_UNDEFINED(declaredNumArgs - actualNumArgs); \
DEPRECATED_CALL_PUSH_ARGS_##ARG_TYPE(); \
} \
goto deprecatedSetVregsAndFrameNotNative; \
} while (false)
#if ECMASCRIPT_ENABLE_IC
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define UPDATE_HOTNESS_COUNTER_NON_ACC(offset) (UpdateHotnessCounter(thread, sp, acc, offset))
#define UPDATE_HOTNESS_COUNTER(offset) \
do { \
if (UpdateHotnessCounter(thread, sp, acc, offset)) { \
HANDLE_EXCEPTION_IF_ABRUPT_COMPLETION(thread); \
RESTORE_ACC(); \
} \
} while (false)
#else
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define UPDATE_HOTNESS_COUNTER(offset) static_cast<void>(0)
#define UPDATE_HOTNESS_COUNTER_NON_ACC(offset) static_cast<void>(0)
#endif
#define READ_INST_OP() READ_INST_8(0) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
#define READ_INST_4_0() (READ_INST_8(1) & 0xf) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
#define READ_INST_4_1() (READ_INST_8(1) >> 4 & 0xf) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
#define READ_INST_4_2() (READ_INST_8(2) & 0xf) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
#define READ_INST_4_3() (READ_INST_8(2) >> 4 & 0xf) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
#define READ_INST_8_0() READ_INST_8(1) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
#define READ_INST_8_1() READ_INST_8(2) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
#define READ_INST_8_2() READ_INST_8(3) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
#define READ_INST_8_3() READ_INST_8(4) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
#define READ_INST_8_4() READ_INST_8(5) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
#define READ_INST_8_5() READ_INST_8(6) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
#define READ_INST_8_6() READ_INST_8(7) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
#define READ_INST_8_7() READ_INST_8(8) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
#define READ_INST_8_8() READ_INST_8(9) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
#define READ_INST_8_9() READ_INST_8(10) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
#define READ_INST_8(offset) (*(pc + (offset)))
#define MOVE_AND_READ_INST_8(currentInst, offset) \
currentInst <<= 8; \
currentInst += READ_INST_8(offset); \
#define READ_INST_16_0() READ_INST_16(2)
#define READ_INST_16_1() READ_INST_16(3)
#define READ_INST_16_2() READ_INST_16(4)
#define READ_INST_16_3() READ_INST_16(5)
#define READ_INST_16_4() READ_INST_16(6)
#define READ_INST_16_5() READ_INST_16(7)
#define READ_INST_16_6() READ_INST_16(8)
#define READ_INST_16_7() READ_INST_16(9)
#define READ_INST_16(offset) \
({ \
uint16_t currentInst = READ_INST_8(offset); \
MOVE_AND_READ_INST_8(currentInst, offset - 1) \
})
#define READ_INST_32_0() READ_INST_32(4)
#define READ_INST_32_1() READ_INST_32(5)
#define READ_INST_32_2() READ_INST_32(6)
#define READ_INST_32(offset) \
({ \
uint32_t currentInst = READ_INST_8(offset); \
MOVE_AND_READ_INST_8(currentInst, offset - 1) \
MOVE_AND_READ_INST_8(currentInst, offset - 2) \
MOVE_AND_READ_INST_8(currentInst, offset - 3) \
})
#define READ_INST_64_0() \
({ \
uint64_t currentInst = READ_INST_8(8); \
MOVE_AND_READ_INST_8(currentInst, 7) \
MOVE_AND_READ_INST_8(currentInst, 6) \
MOVE_AND_READ_INST_8(currentInst, 5) \
MOVE_AND_READ_INST_8(currentInst, 4) \
MOVE_AND_READ_INST_8(currentInst, 3) \
MOVE_AND_READ_INST_8(currentInst, 2) \
MOVE_AND_READ_INST_8(currentInst, 1) \
})
#undef LOG_INST
#undef HANDLE_OPCODE
#undef ADVANCE_PC
#undef GOTO_NEXT
#undef DISPATCH
#undef DISPATCH_OFFSET
#undef GET_FRAME
#undef GET_ENTRY_FRAME
#undef SAVE_PC
#undef SAVE_ACC
#undef RESTORE_ACC
#undef INTERPRETER_GOTO_EXCEPTION_HANDLER
#undef CHECK_SWITCH_TO_DEBUGGER_TABLE
#undef REAL_GOTO_DISPATCH_OPCODE
#undef REAL_GOTO_EXCEPTION_HANDLER
#undef INTERPRETER_RETURN_IF_ABRUPT
#undef NOTIFY_DEBUGGER_EVENT
#undef DEPRECATED_CALL_INITIALIZE
#undef CALL_PUSH_UNDEFINED
#undef DEPRECATED_CALL_PUSH_ARGS_0
#undef DEPRECATED_CALL_PUSH_ARGS_1
#undef DEPRECATED_CALL_PUSH_ARGS_2
#undef DEPRECATED_CALL_PUSH_ARGS_3
#undef DEPRECATED_CALL_PUSH_ARGS_RANGE
#undef DEPRECATED_CALL_PUSH_ARGS_THISRANGE
#undef DEPRECATED_CALL_PUSH_ARGS_0_NO_EXTRA
#undef DEPRECATED_CALL_PUSH_ARGS_1_NO_EXTRA
#undef DEPRECATED_CALL_PUSH_ARGS_2_NO_EXTRA
#undef DEPRECATED_CALL_PUSH_ARGS_3_NO_EXTRA
#undef DEPRECATED_CALL_PUSH_ARGS_RANGE_NO_EXTRA
#undef DEPRECATED_CALL_PUSH_ARGS_THISRANGE_NO_EXTRA
#undef DEPRECATED_CALL_PUSH_ARGS
#undef UPDATE_HOTNESS_COUNTER_NON_ACC
#undef UPDATE_HOTNESS_COUNTER
#undef GET_VREG
#undef GET_VREG_VALUE
#undef SET_VREG
#undef GET_ACC
#undef SET_ACC
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
} // namespace panda::ecmascript
#endif // ECMASCRIPT_INTERPRETER_INTERPRETER_INL_H