14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#include "ecmascript/debugger/dropframe_manager.h" 174514f5e3Sopenharmony_ci 184514f5e3Sopenharmony_ci#include "ecmascript/interpreter/interpreter-inl.h" 194514f5e3Sopenharmony_ci#include "ecmascript/jobs/micro_job_queue.h" 204514f5e3Sopenharmony_ci 214514f5e3Sopenharmony_cinamespace panda::ecmascript::tooling { 224514f5e3Sopenharmony_cibool DropframeManager::IsNewlexenvOpcode(BytecodeInstruction::Opcode op) 234514f5e3Sopenharmony_ci{ 244514f5e3Sopenharmony_ci switch (op) { 254514f5e3Sopenharmony_ci case BytecodeInstruction::Opcode::NEWLEXENV_IMM8: 264514f5e3Sopenharmony_ci case BytecodeInstruction::Opcode::NEWLEXENVWITHNAME_IMM8_ID16: 274514f5e3Sopenharmony_ci case BytecodeInstruction::Opcode::WIDE_NEWLEXENV_PREF_IMM16: 284514f5e3Sopenharmony_ci case BytecodeInstruction::Opcode::WIDE_NEWLEXENVWITHNAME_PREF_IMM16_ID16: 294514f5e3Sopenharmony_ci return true; 304514f5e3Sopenharmony_ci default: 314514f5e3Sopenharmony_ci break; 324514f5e3Sopenharmony_ci } 334514f5e3Sopenharmony_ci return false; 344514f5e3Sopenharmony_ci} 354514f5e3Sopenharmony_ci 364514f5e3Sopenharmony_cibool DropframeManager::IsStlexvarOpcode(BytecodeInstruction::Opcode op) 374514f5e3Sopenharmony_ci{ 384514f5e3Sopenharmony_ci switch (op) { 394514f5e3Sopenharmony_ci case BytecodeInstruction::Opcode::STLEXVAR_IMM4_IMM4: 404514f5e3Sopenharmony_ci case BytecodeInstruction::Opcode::STLEXVAR_IMM8_IMM8: 414514f5e3Sopenharmony_ci case BytecodeInstruction::Opcode::WIDE_STLEXVAR_PREF_IMM16_IMM16: 424514f5e3Sopenharmony_ci return true; 434514f5e3Sopenharmony_ci default: 444514f5e3Sopenharmony_ci break; 454514f5e3Sopenharmony_ci } 464514f5e3Sopenharmony_ci return false; 474514f5e3Sopenharmony_ci} 484514f5e3Sopenharmony_ci 494514f5e3Sopenharmony_cistd::pair<uint16_t, uint16_t> DropframeManager::ReadStlexvarParams(const uint8_t *pc, BytecodeInstruction::Opcode op) 504514f5e3Sopenharmony_ci{ 514514f5e3Sopenharmony_ci uint16_t level = 0; 524514f5e3Sopenharmony_ci uint16_t slot = 0; 534514f5e3Sopenharmony_ci switch (op) { 544514f5e3Sopenharmony_ci case BytecodeInstruction::Opcode::STLEXVAR_IMM4_IMM4: 554514f5e3Sopenharmony_ci level = READ_INST_4_0(); 564514f5e3Sopenharmony_ci slot = READ_INST_4_1(); 574514f5e3Sopenharmony_ci break; 584514f5e3Sopenharmony_ci case BytecodeInstruction::Opcode::STLEXVAR_IMM8_IMM8: 594514f5e3Sopenharmony_ci level = READ_INST_8_0(); 604514f5e3Sopenharmony_ci slot = READ_INST_8_1(); 614514f5e3Sopenharmony_ci break; 624514f5e3Sopenharmony_ci case BytecodeInstruction::Opcode::WIDE_STLEXVAR_PREF_IMM16_IMM16: 634514f5e3Sopenharmony_ci level = READ_INST_16_1(); 644514f5e3Sopenharmony_ci slot = READ_INST_16_3(); 654514f5e3Sopenharmony_ci break; 664514f5e3Sopenharmony_ci default: 674514f5e3Sopenharmony_ci break; 684514f5e3Sopenharmony_ci } 694514f5e3Sopenharmony_ci return std::make_pair(level, slot); 704514f5e3Sopenharmony_ci} 714514f5e3Sopenharmony_ci 724514f5e3Sopenharmony_civoid DropframeManager::MethodEntry(JSThread *thread, JSHandle<Method> method, JSHandle<JSTaggedValue> envHandle) 734514f5e3Sopenharmony_ci{ 744514f5e3Sopenharmony_ci std::set<std::pair<uint16_t, uint16_t>> modifiedLexVarPos; 754514f5e3Sopenharmony_ci const JSPandaFile* methodJsPandaFile = method->GetJSPandaFile(); 764514f5e3Sopenharmony_ci panda_file::File::EntityId methodId = method->GetMethodId(); 774514f5e3Sopenharmony_ci PushMethodInfo(std::make_tuple(const_cast<JSPandaFile *>(methodJsPandaFile), methodId)); 784514f5e3Sopenharmony_ci if (method->IsSendableMethod()) { 794514f5e3Sopenharmony_ci PushMethodType(MethodType::SENDABLE_METHOD); 804514f5e3Sopenharmony_ci return; 814514f5e3Sopenharmony_ci } 824514f5e3Sopenharmony_ci NewLexModifyRecordLevel(); 834514f5e3Sopenharmony_ci PushPromiseQueueSizeRecord(thread); 844514f5e3Sopenharmony_ci if (!envHandle->IsLexicalEnv()) { 854514f5e3Sopenharmony_ci PushMethodType(MethodType::OTHER_METHOD); 864514f5e3Sopenharmony_ci return; 874514f5e3Sopenharmony_ci } 884514f5e3Sopenharmony_ci PushMethodType(MethodType::NORMAL_METHOD); 894514f5e3Sopenharmony_ci uint32_t codeSize = method->GetCodeSize(); 904514f5e3Sopenharmony_ci uint16_t newEnvCount = 0; 914514f5e3Sopenharmony_ci auto bcIns = BytecodeInstruction(method->GetBytecodeArray()); 924514f5e3Sopenharmony_ci auto bcInsLast = bcIns.JumpTo(codeSize); 934514f5e3Sopenharmony_ci while (bcIns.GetAddress() != bcInsLast.GetAddress()) { 944514f5e3Sopenharmony_ci AddLexPropertiesToRecord(thread, bcIns, newEnvCount, modifiedLexVarPos, envHandle); 954514f5e3Sopenharmony_ci bcIns = bcIns.GetNext(); 964514f5e3Sopenharmony_ci } 974514f5e3Sopenharmony_ci} 984514f5e3Sopenharmony_ci 994514f5e3Sopenharmony_civoid DropframeManager::AddLexPropertiesToRecord(JSThread *thread, BytecodeInstruction &bcIns, uint16_t &newEnvCount, 1004514f5e3Sopenharmony_ci std::set<std::pair<uint16_t, uint16_t>> &modifiedLexVarPos, JSHandle<JSTaggedValue> envHandle) 1014514f5e3Sopenharmony_ci{ 1024514f5e3Sopenharmony_ci BytecodeInstruction::Opcode op = bcIns.GetOpcode(); 1034514f5e3Sopenharmony_ci if (IsNewlexenvOpcode(op)) { 1044514f5e3Sopenharmony_ci newEnvCount++; 1054514f5e3Sopenharmony_ci return; 1064514f5e3Sopenharmony_ci } 1074514f5e3Sopenharmony_ci if (IsStlexvarOpcode(op)) { 1084514f5e3Sopenharmony_ci std::pair<uint16_t, uint16_t> lexVarPos = ReadStlexvarParams(bcIns.GetAddress(), op); 1094514f5e3Sopenharmony_ci uint16_t level; 1104514f5e3Sopenharmony_ci uint16_t slot; 1114514f5e3Sopenharmony_ci std::tie(level, slot) = lexVarPos; 1124514f5e3Sopenharmony_ci JSTaggedValue env = envHandle.GetTaggedValue(); 1134514f5e3Sopenharmony_ci for (uint16_t i = 0; ; i++) { 1144514f5e3Sopenharmony_ci if ((level < newEnvCount || i >= level - newEnvCount) && 1154514f5e3Sopenharmony_ci slot < LexicalEnv::Cast(env.GetTaggedObject())->GetLength() - LexicalEnv::RESERVED_ENV_LENGTH && 1164514f5e3Sopenharmony_ci !modifiedLexVarPos.count({i, slot})) { 1174514f5e3Sopenharmony_ci JSTaggedValue value = LexicalEnv::Cast(env.GetTaggedObject())->GetProperties(slot); 1184514f5e3Sopenharmony_ci EmplaceLexModifyRecord(thread, env, slot, value); 1194514f5e3Sopenharmony_ci modifiedLexVarPos.insert({i, slot}); 1204514f5e3Sopenharmony_ci } 1214514f5e3Sopenharmony_ci if (i >= level) { 1224514f5e3Sopenharmony_ci break; 1234514f5e3Sopenharmony_ci } 1244514f5e3Sopenharmony_ci JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv(); 1254514f5e3Sopenharmony_ci if (!taggedParentEnv.IsLexicalEnv()) { 1264514f5e3Sopenharmony_ci break; 1274514f5e3Sopenharmony_ci } 1284514f5e3Sopenharmony_ci env = taggedParentEnv; 1294514f5e3Sopenharmony_ci } 1304514f5e3Sopenharmony_ci } 1314514f5e3Sopenharmony_ci} 1324514f5e3Sopenharmony_ci 1334514f5e3Sopenharmony_civoid DropframeManager::MethodExit(JSThread *thread, [[maybe_unused]] JSHandle<Method> method) 1344514f5e3Sopenharmony_ci{ 1354514f5e3Sopenharmony_ci const JSPandaFile* methodJsPandaFile = method->GetJSPandaFile(); 1364514f5e3Sopenharmony_ci panda_file::File::EntityId methodId = method->GetMethodId(); 1374514f5e3Sopenharmony_ci if (!CheckExitMethodInfo(std::make_tuple(const_cast<JSPandaFile *>(methodJsPandaFile), methodId))) { 1384514f5e3Sopenharmony_ci return; 1394514f5e3Sopenharmony_ci } 1404514f5e3Sopenharmony_ci PopMethodInfo(); 1414514f5e3Sopenharmony_ci if (CheckIsSendableMethod()) { 1424514f5e3Sopenharmony_ci PopMethodType(); 1434514f5e3Sopenharmony_ci return; 1444514f5e3Sopenharmony_ci } 1454514f5e3Sopenharmony_ci PopMethodType(); 1464514f5e3Sopenharmony_ci MergeLexModifyRecordOfTopFrame(thread); 1474514f5e3Sopenharmony_ci PopPromiseQueueSizeRecord(); 1484514f5e3Sopenharmony_ci} 1494514f5e3Sopenharmony_ci 1504514f5e3Sopenharmony_civoid DropframeManager::DropLastFrame(JSThread *thread) 1514514f5e3Sopenharmony_ci{ 1524514f5e3Sopenharmony_ci std::vector<std::tuple<JSHandle<JSTaggedValue>, uint16_t, JSHandle<JSTaggedValue>>> lexModifyRecord; 1534514f5e3Sopenharmony_ci lexModifyRecord = GetLexModifyRecordOfTopFrame(); 1544514f5e3Sopenharmony_ci for (const auto &item : lexModifyRecord) { 1554514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> envHandle; 1564514f5e3Sopenharmony_ci uint16_t slot; 1574514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valueHandle; 1584514f5e3Sopenharmony_ci std::tie(envHandle, slot, valueHandle) = item; 1594514f5e3Sopenharmony_ci JSTaggedValue env = envHandle.GetTaggedValue(); 1604514f5e3Sopenharmony_ci ASSERT(slot < LexicalEnv::Cast(env.GetTaggedObject())->GetLength() - LexicalEnv::RESERVED_ENV_LENGTH); 1614514f5e3Sopenharmony_ci LexicalEnv::Cast(env.GetTaggedObject())->SetProperties(thread, slot, valueHandle.GetTaggedValue()); 1624514f5e3Sopenharmony_ci } 1634514f5e3Sopenharmony_ci PopMethodInfo(); 1644514f5e3Sopenharmony_ci PopMethodType(); 1654514f5e3Sopenharmony_ci RemoveLexModifyRecordOfTopFrame(thread); 1664514f5e3Sopenharmony_ci PopPromiseQueueSizeRecord(); 1674514f5e3Sopenharmony_ci 1684514f5e3Sopenharmony_ci FrameHandler frameHandler(thread); 1694514f5e3Sopenharmony_ci bool isEntryFrameDropped = false; 1704514f5e3Sopenharmony_ci while (frameHandler.HasFrame()) { 1714514f5e3Sopenharmony_ci frameHandler.PrevJSFrame(); 1724514f5e3Sopenharmony_ci if (frameHandler.IsEntryFrame()) { 1734514f5e3Sopenharmony_ci isEntryFrameDropped = true; 1744514f5e3Sopenharmony_ci continue; 1754514f5e3Sopenharmony_ci } 1764514f5e3Sopenharmony_ci if (frameHandler.IsBuiltinFrame()) { 1774514f5e3Sopenharmony_ci continue; 1784514f5e3Sopenharmony_ci } 1794514f5e3Sopenharmony_ci if (!thread->IsAsmInterpreter()) { 1804514f5e3Sopenharmony_ci JSTaggedType *prevSp = frameHandler.GetSp(); 1814514f5e3Sopenharmony_ci thread->SetCurrentFrame(prevSp); 1824514f5e3Sopenharmony_ci } 1834514f5e3Sopenharmony_ci if (isEntryFrameDropped) { 1844514f5e3Sopenharmony_ci thread->SetEntryFrameDroppedState(); 1854514f5e3Sopenharmony_ci } 1864514f5e3Sopenharmony_ci thread->SetFrameDroppedState(); 1874514f5e3Sopenharmony_ci break; 1884514f5e3Sopenharmony_ci } 1894514f5e3Sopenharmony_ci} 1904514f5e3Sopenharmony_ci 1914514f5e3Sopenharmony_civoid DropframeManager::NewLexModifyRecordLevel() 1924514f5e3Sopenharmony_ci{ 1934514f5e3Sopenharmony_ci modifiedLexVar_.push(std::vector<std::tuple<JSHandle<JSTaggedValue>, uint16_t, JSHandle<JSTaggedValue>>>()); 1944514f5e3Sopenharmony_ci} 1954514f5e3Sopenharmony_ci 1964514f5e3Sopenharmony_civoid DropframeManager::EmplaceLexModifyRecord(JSThread *thread, JSTaggedValue env, uint16_t slot, JSTaggedValue value) 1974514f5e3Sopenharmony_ci{ 1984514f5e3Sopenharmony_ci GlobalHandleCollection globalHandleCollection(thread); 1994514f5e3Sopenharmony_ci for (const auto &item : modifiedLexVar_.top()) { 2004514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> envHandleRecord = std::get<0>(item); 2014514f5e3Sopenharmony_ci uint16_t slotRecord = std::get<1>(item); 2024514f5e3Sopenharmony_ci if (envHandleRecord.GetTaggedType() == env.GetRawData() && slotRecord == slot) { 2034514f5e3Sopenharmony_ci return; 2044514f5e3Sopenharmony_ci } 2054514f5e3Sopenharmony_ci } 2064514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> envHandle = globalHandleCollection.NewHandle<JSTaggedValue>(env.GetRawData()); 2074514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valueHandle = globalHandleCollection.NewHandle<JSTaggedValue>(value.GetRawData()); 2084514f5e3Sopenharmony_ci modifiedLexVar_.top().emplace_back(envHandle, slot, valueHandle); 2094514f5e3Sopenharmony_ci} 2104514f5e3Sopenharmony_ci 2114514f5e3Sopenharmony_ciuint32_t DropframeManager::GetLexModifyRecordLevel() 2124514f5e3Sopenharmony_ci{ 2134514f5e3Sopenharmony_ci return modifiedLexVar_.size(); 2144514f5e3Sopenharmony_ci} 2154514f5e3Sopenharmony_ci 2164514f5e3Sopenharmony_cistd::vector<std::tuple<JSHandle<JSTaggedValue>, uint16_t, JSHandle<JSTaggedValue>>> 2174514f5e3Sopenharmony_ci DropframeManager::GetLexModifyRecordOfTopFrame() 2184514f5e3Sopenharmony_ci{ 2194514f5e3Sopenharmony_ci if (modifiedLexVar_.empty()) { 2204514f5e3Sopenharmony_ci return std::vector<std::tuple<JSHandle<JSTaggedValue>, uint16_t, JSHandle<JSTaggedValue>>>(); 2214514f5e3Sopenharmony_ci } 2224514f5e3Sopenharmony_ci return modifiedLexVar_.top(); 2234514f5e3Sopenharmony_ci} 2244514f5e3Sopenharmony_ci 2254514f5e3Sopenharmony_civoid DropframeManager::RemoveLexModifyRecordOfTopFrame(JSThread *thread) 2264514f5e3Sopenharmony_ci{ 2274514f5e3Sopenharmony_ci if (modifiedLexVar_.empty()) { 2284514f5e3Sopenharmony_ci return; 2294514f5e3Sopenharmony_ci } 2304514f5e3Sopenharmony_ci GlobalHandleCollection globalHandleCollection(thread); 2314514f5e3Sopenharmony_ci for (const auto &item : modifiedLexVar_.top()) { 2324514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> envHandle = std::get<0>(item); 2334514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valueHandle = std::get<2>(item); // 2:get the third item of the tuple 2344514f5e3Sopenharmony_ci globalHandleCollection.Dispose(envHandle); 2354514f5e3Sopenharmony_ci globalHandleCollection.Dispose(valueHandle); 2364514f5e3Sopenharmony_ci } 2374514f5e3Sopenharmony_ci modifiedLexVar_.pop(); 2384514f5e3Sopenharmony_ci} 2394514f5e3Sopenharmony_ci 2404514f5e3Sopenharmony_civoid DropframeManager::MergeLexModifyRecordOfTopFrame(JSThread *thread) 2414514f5e3Sopenharmony_ci{ 2424514f5e3Sopenharmony_ci if (modifiedLexVar_.empty()) { 2434514f5e3Sopenharmony_ci return; 2444514f5e3Sopenharmony_ci } 2454514f5e3Sopenharmony_ci GlobalHandleCollection globalHandleCollection(thread); 2464514f5e3Sopenharmony_ci std::vector<std::tuple<JSHandle<JSTaggedValue>, uint16_t, JSHandle<JSTaggedValue>>> lexModifyRecord; 2474514f5e3Sopenharmony_ci lexModifyRecord = modifiedLexVar_.top(); 2484514f5e3Sopenharmony_ci modifiedLexVar_.pop(); 2494514f5e3Sopenharmony_ci if (!modifiedLexVar_.empty() && modifiedLexVar_.top().empty()) { 2504514f5e3Sopenharmony_ci modifiedLexVar_.pop(); 2514514f5e3Sopenharmony_ci modifiedLexVar_.push(lexModifyRecord); 2524514f5e3Sopenharmony_ci return; 2534514f5e3Sopenharmony_ci } 2544514f5e3Sopenharmony_ci for (const auto &item : lexModifyRecord) { 2554514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> envHandle; 2564514f5e3Sopenharmony_ci uint16_t slot; 2574514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valueHandle; 2584514f5e3Sopenharmony_ci std::tie(envHandle, slot, valueHandle) = item; 2594514f5e3Sopenharmony_ci bool existRecord = false; 2604514f5e3Sopenharmony_ci if (!modifiedLexVar_.empty()) { 2614514f5e3Sopenharmony_ci for (const auto &itemLast : modifiedLexVar_.top()) { 2624514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> envHandleRecord = std::get<0>(itemLast); 2634514f5e3Sopenharmony_ci uint16_t slotRecord = std::get<1>(itemLast); 2644514f5e3Sopenharmony_ci if (envHandleRecord.GetTaggedType() == envHandle.GetTaggedType() && slotRecord == slot) { 2654514f5e3Sopenharmony_ci existRecord = true; 2664514f5e3Sopenharmony_ci break; 2674514f5e3Sopenharmony_ci } 2684514f5e3Sopenharmony_ci } 2694514f5e3Sopenharmony_ci } 2704514f5e3Sopenharmony_ci if (modifiedLexVar_.empty() || existRecord) { 2714514f5e3Sopenharmony_ci globalHandleCollection.Dispose(envHandle); 2724514f5e3Sopenharmony_ci globalHandleCollection.Dispose(valueHandle); 2734514f5e3Sopenharmony_ci } else { 2744514f5e3Sopenharmony_ci modifiedLexVar_.top().emplace_back(envHandle, slot, valueHandle); 2754514f5e3Sopenharmony_ci } 2764514f5e3Sopenharmony_ci } 2774514f5e3Sopenharmony_ci} 2784514f5e3Sopenharmony_ci 2794514f5e3Sopenharmony_civoid DropframeManager::PushPromiseQueueSizeRecord(JSThread *thread) 2804514f5e3Sopenharmony_ci{ 2814514f5e3Sopenharmony_ci EcmaContext *context = thread->GetCurrentEcmaContext(); 2824514f5e3Sopenharmony_ci uint32_t queueSize = job::MicroJobQueue::GetPromiseQueueSize(thread, context->GetMicroJobQueue()); 2834514f5e3Sopenharmony_ci promiseQueueSizeRecord_.push(queueSize); 2844514f5e3Sopenharmony_ci} 2854514f5e3Sopenharmony_ci 2864514f5e3Sopenharmony_ciuint32_t DropframeManager::GetPromiseQueueSizeRecordOfTopFrame() 2874514f5e3Sopenharmony_ci{ 2884514f5e3Sopenharmony_ci ASSERT(!promiseQueueSizeRecord_.empty()); 2894514f5e3Sopenharmony_ci return promiseQueueSizeRecord_.top(); 2904514f5e3Sopenharmony_ci} 2914514f5e3Sopenharmony_ci 2924514f5e3Sopenharmony_civoid DropframeManager::PopPromiseQueueSizeRecord() 2934514f5e3Sopenharmony_ci{ 2944514f5e3Sopenharmony_ci if (!promiseQueueSizeRecord_.empty()) { 2954514f5e3Sopenharmony_ci promiseQueueSizeRecord_.pop(); 2964514f5e3Sopenharmony_ci } 2974514f5e3Sopenharmony_ci} 2984514f5e3Sopenharmony_ci 2994514f5e3Sopenharmony_civoid DropframeManager::PushMethodInfo(std::tuple<JSPandaFile*, 3004514f5e3Sopenharmony_ci panda_file::File::EntityId> methodInfo) 3014514f5e3Sopenharmony_ci{ 3024514f5e3Sopenharmony_ci methodInfo_.push(methodInfo); 3034514f5e3Sopenharmony_ci} 3044514f5e3Sopenharmony_ci 3054514f5e3Sopenharmony_cibool DropframeManager::CheckExitMethodInfo(std::tuple<JSPandaFile*, 3064514f5e3Sopenharmony_ci panda_file::File::EntityId> methodInfo) 3074514f5e3Sopenharmony_ci{ 3084514f5e3Sopenharmony_ci if (methodInfo_.empty()) { 3094514f5e3Sopenharmony_ci return false; 3104514f5e3Sopenharmony_ci } 3114514f5e3Sopenharmony_ci if (methodInfo == methodInfo_.top()) { 3124514f5e3Sopenharmony_ci return true; 3134514f5e3Sopenharmony_ci } 3144514f5e3Sopenharmony_ci return false; 3154514f5e3Sopenharmony_ci} 3164514f5e3Sopenharmony_ci 3174514f5e3Sopenharmony_civoid DropframeManager::PopMethodInfo() 3184514f5e3Sopenharmony_ci{ 3194514f5e3Sopenharmony_ci if (!methodInfo_.empty()) { 3204514f5e3Sopenharmony_ci methodInfo_.pop(); 3214514f5e3Sopenharmony_ci } 3224514f5e3Sopenharmony_ci} 3234514f5e3Sopenharmony_ci 3244514f5e3Sopenharmony_civoid DropframeManager::PushMethodType(MethodType methodType) 3254514f5e3Sopenharmony_ci{ 3264514f5e3Sopenharmony_ci methodType_.push(methodType); 3274514f5e3Sopenharmony_ci} 3284514f5e3Sopenharmony_ci 3294514f5e3Sopenharmony_cibool DropframeManager::CheckIsSendableMethod() 3304514f5e3Sopenharmony_ci{ 3314514f5e3Sopenharmony_ci ASSERT(!methodType_.empty()); 3324514f5e3Sopenharmony_ci return methodType_.top() == MethodType::SENDABLE_METHOD; 3334514f5e3Sopenharmony_ci} 3344514f5e3Sopenharmony_ci 3354514f5e3Sopenharmony_civoid DropframeManager::PopMethodType() 3364514f5e3Sopenharmony_ci{ 3374514f5e3Sopenharmony_ci if (!methodType_.empty()) { 3384514f5e3Sopenharmony_ci methodType_.pop(); 3394514f5e3Sopenharmony_ci } 3404514f5e3Sopenharmony_ci} 3414514f5e3Sopenharmony_ci}