13af6ab5fSopenharmony_ci/* 23af6ab5fSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License. 53af6ab5fSopenharmony_ci * You may obtain a copy of the License at 63af6ab5fSopenharmony_ci * 73af6ab5fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 83af6ab5fSopenharmony_ci * 93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and 133af6ab5fSopenharmony_ci * limitations under the License. 143af6ab5fSopenharmony_ci */ 153af6ab5fSopenharmony_ci 163af6ab5fSopenharmony_ci#include "patchFix.h" 173af6ab5fSopenharmony_ci#include <binder/binder.h> 183af6ab5fSopenharmony_ci#include <binder/scope.h> 193af6ab5fSopenharmony_ci#include <binder/variable.h> 203af6ab5fSopenharmony_ci#include <compiler/core/pandagen.h> 213af6ab5fSopenharmony_ci#include <ir/expressions/literal.h> 223af6ab5fSopenharmony_ci 233af6ab5fSopenharmony_ci#include <fstream> 243af6ab5fSopenharmony_ci#include <iostream> 253af6ab5fSopenharmony_ci#include <string> 263af6ab5fSopenharmony_ci#include <unistd.h> 273af6ab5fSopenharmony_ci 283af6ab5fSopenharmony_cinamespace panda::es2panda::util { 293af6ab5fSopenharmony_ci 303af6ab5fSopenharmony_ciconst std::string EXTERNAL_ATTRIBUTE = "external"; 313af6ab5fSopenharmony_ciconst panda::panda_file::SourceLang SRC_LANG = panda::panda_file::SourceLang::ECMASCRIPT; 323af6ab5fSopenharmony_ci 333af6ab5fSopenharmony_civoid PatchFix::ProcessFunction(const compiler::PandaGen *pg, panda::pandasm::Function *func, 343af6ab5fSopenharmony_ci LiteralBuffers &literalBuffers) 353af6ab5fSopenharmony_ci{ 363af6ab5fSopenharmony_ci if (generateSymbolFile_) { 373af6ab5fSopenharmony_ci DumpFunctionInfo(pg, func, literalBuffers); 383af6ab5fSopenharmony_ci return; 393af6ab5fSopenharmony_ci } 403af6ab5fSopenharmony_ci 413af6ab5fSopenharmony_ci if (generatePatch_ || IsHotReload()) { 423af6ab5fSopenharmony_ci HandleFunction(pg, func, literalBuffers); 433af6ab5fSopenharmony_ci return; 443af6ab5fSopenharmony_ci } 453af6ab5fSopenharmony_ci} 463af6ab5fSopenharmony_ci 473af6ab5fSopenharmony_civoid PatchFix::ProcessModule(const std::string &recordName, 483af6ab5fSopenharmony_ci std::vector<panda::pandasm::LiteralArray::Literal> &moduleBuffer) 493af6ab5fSopenharmony_ci{ 503af6ab5fSopenharmony_ci if (generateSymbolFile_) { 513af6ab5fSopenharmony_ci DumpModuleInfo(recordName, moduleBuffer); 523af6ab5fSopenharmony_ci return; 533af6ab5fSopenharmony_ci } 543af6ab5fSopenharmony_ci 553af6ab5fSopenharmony_ci if (generatePatch_ || IsHotReload()) { 563af6ab5fSopenharmony_ci ValidateModuleInfo(recordName, moduleBuffer); 573af6ab5fSopenharmony_ci return; 583af6ab5fSopenharmony_ci } 593af6ab5fSopenharmony_ci} 603af6ab5fSopenharmony_ci 613af6ab5fSopenharmony_civoid PatchFix::ProcessJsonContentRecord(const std::string &recordName, const std::string &jsonFileContent) 623af6ab5fSopenharmony_ci{ 633af6ab5fSopenharmony_ci if (generateSymbolFile_) { 643af6ab5fSopenharmony_ci DumpJsonContentRecInfo(recordName, jsonFileContent); 653af6ab5fSopenharmony_ci return; 663af6ab5fSopenharmony_ci } 673af6ab5fSopenharmony_ci 683af6ab5fSopenharmony_ci if (generatePatch_ || IsHotReload()) { 693af6ab5fSopenharmony_ci ValidateJsonContentRecInfo(recordName, jsonFileContent); 703af6ab5fSopenharmony_ci return; 713af6ab5fSopenharmony_ci } 723af6ab5fSopenharmony_ci} 733af6ab5fSopenharmony_ci 743af6ab5fSopenharmony_civoid PatchFix::DumpModuleInfo(const std::string &recordName, 753af6ab5fSopenharmony_ci std::vector<panda::pandasm::LiteralArray::Literal> &moduleBuffer) 763af6ab5fSopenharmony_ci{ 773af6ab5fSopenharmony_ci std::stringstream ss; 783af6ab5fSopenharmony_ci ss << recordName << SymbolTable::SECOND_LEVEL_SEPERATOR; 793af6ab5fSopenharmony_ci ss << Helpers::GetHashString(ConvertLiteralToString(moduleBuffer)) << std::endl; 803af6ab5fSopenharmony_ci symbolTable_->FillSymbolTable(ss); 813af6ab5fSopenharmony_ci} 823af6ab5fSopenharmony_ci 833af6ab5fSopenharmony_civoid PatchFix::ValidateModuleInfo(const std::string &recordName, 843af6ab5fSopenharmony_ci std::vector<panda::pandasm::LiteralArray::Literal> &moduleBuffer) 853af6ab5fSopenharmony_ci{ 863af6ab5fSopenharmony_ci auto it = originModuleInfo_->find(recordName); 873af6ab5fSopenharmony_ci if (!IsHotReload() && it == originModuleInfo_->end()) { 883af6ab5fSopenharmony_ci std::cerr << "[Patch] Found new import/export expression in " << recordName << ", not supported!" << std::endl; 893af6ab5fSopenharmony_ci patchError_ = true; 903af6ab5fSopenharmony_ci return; 913af6ab5fSopenharmony_ci } 923af6ab5fSopenharmony_ci 933af6ab5fSopenharmony_ci if (!IsHotReload() && Helpers::GetHashString(ConvertLiteralToString(moduleBuffer)) != it->second) { 943af6ab5fSopenharmony_ci std::cerr << "[Patch] Found import/export expression changed in " << recordName << ", not supported!" << 953af6ab5fSopenharmony_ci std::endl; 963af6ab5fSopenharmony_ci patchError_ = true; 973af6ab5fSopenharmony_ci return; 983af6ab5fSopenharmony_ci } 993af6ab5fSopenharmony_ci} 1003af6ab5fSopenharmony_ci 1013af6ab5fSopenharmony_civoid PatchFix::DumpJsonContentRecInfo(const std::string &recordName, const std::string &jsonFileContent) 1023af6ab5fSopenharmony_ci{ 1033af6ab5fSopenharmony_ci std::stringstream ss; 1043af6ab5fSopenharmony_ci ss << recordName << SymbolTable::SECOND_LEVEL_SEPERATOR; 1053af6ab5fSopenharmony_ci ss << Helpers::GetHashString(jsonFileContent) << std::endl; 1063af6ab5fSopenharmony_ci symbolTable_->FillSymbolTable(ss); 1073af6ab5fSopenharmony_ci} 1083af6ab5fSopenharmony_ci 1093af6ab5fSopenharmony_civoid PatchFix::ValidateJsonContentRecInfo(const std::string &recordName, const std::string &jsonFileContent) 1103af6ab5fSopenharmony_ci{ 1113af6ab5fSopenharmony_ci auto it = originModuleInfo_->find(recordName); 1123af6ab5fSopenharmony_ci if (!IsHotReload() && it == originModuleInfo_->end()) { 1133af6ab5fSopenharmony_ci std::cerr << "[Patch] Found new import/require json file expression in " << recordName << 1143af6ab5fSopenharmony_ci ", not supported!" << std::endl; 1153af6ab5fSopenharmony_ci patchError_ = true; 1163af6ab5fSopenharmony_ci return; 1173af6ab5fSopenharmony_ci } 1183af6ab5fSopenharmony_ci 1193af6ab5fSopenharmony_ci if (!IsHotReload() && Helpers::GetHashString(jsonFileContent) != it->second) { 1203af6ab5fSopenharmony_ci std::cerr << "[Patch] Found imported/required json file content changed in " << recordName << 1213af6ab5fSopenharmony_ci ", not supported!" << std::endl; 1223af6ab5fSopenharmony_ci patchError_ = true; 1233af6ab5fSopenharmony_ci return; 1243af6ab5fSopenharmony_ci } 1253af6ab5fSopenharmony_ci} 1263af6ab5fSopenharmony_ci 1273af6ab5fSopenharmony_cibool PatchFix::IsAnonymousOrSpecialOrDuplicateFunction(const std::string &funcName) 1283af6ab5fSopenharmony_ci{ 1293af6ab5fSopenharmony_ci if (util::Helpers::IsDefaultApiVersion(targetApiVersion_, targetApiSubVersion_)) { 1303af6ab5fSopenharmony_ci return funcName.find(binder::Binder::ANONYMOUS_SPECIAL_DUPLICATE_FUNCTION_SPECIFIER) != std::string::npos; 1313af6ab5fSopenharmony_ci } 1323af6ab5fSopenharmony_ci // Function name is like: #scopes^1#functionname^1 1333af6ab5fSopenharmony_ci // Special function name is which includes "\\" or ".", the name should be transformed into "". 1343af6ab5fSopenharmony_ci // Anonymous function name is "", it's the same with special function name here. 1353af6ab5fSopenharmony_ci // Duplicate function name includes "^" after the last "#". 1363af6ab5fSopenharmony_ci auto pos = funcName.find_last_of(Helpers::FUNC_NAME_SEPARATOR); 1373af6ab5fSopenharmony_ci if (pos == std::string::npos) { 1383af6ab5fSopenharmony_ci return false; 1393af6ab5fSopenharmony_ci } 1403af6ab5fSopenharmony_ci 1413af6ab5fSopenharmony_ci if (pos == funcName.size() - 1) { 1423af6ab5fSopenharmony_ci return true; 1433af6ab5fSopenharmony_ci } 1443af6ab5fSopenharmony_ci 1453af6ab5fSopenharmony_ci auto posOfDuplicateSep = funcName.find_last_of(Helpers::DUPLICATED_SEPERATOR); 1463af6ab5fSopenharmony_ci if (posOfDuplicateSep != std::string::npos && posOfDuplicateSep > pos) { 1473af6ab5fSopenharmony_ci return true; 1483af6ab5fSopenharmony_ci } 1493af6ab5fSopenharmony_ci 1503af6ab5fSopenharmony_ci return false; 1513af6ab5fSopenharmony_ci} 1523af6ab5fSopenharmony_ci 1533af6ab5fSopenharmony_ciint64_t PatchFix::GetLiteralIdxFromStringId(const std::string &stringId) 1543af6ab5fSopenharmony_ci{ 1553af6ab5fSopenharmony_ci auto recordPrefix = recordName_ + "_"; 1563af6ab5fSopenharmony_ci auto idxStr = stringId.substr(recordPrefix.size()); 1573af6ab5fSopenharmony_ci return std::atoi(idxStr.c_str()); 1583af6ab5fSopenharmony_ci} 1593af6ab5fSopenharmony_ci 1603af6ab5fSopenharmony_civoid PatchFix::CollectFunctionsWithDefinedClasses(std::string funcName, std::string className) 1613af6ab5fSopenharmony_ci{ 1623af6ab5fSopenharmony_ci auto funcInfo = funcDefinedClasses_.find(funcName); 1633af6ab5fSopenharmony_ci if (funcInfo != funcDefinedClasses_.end()) { 1643af6ab5fSopenharmony_ci funcInfo->second.push_back(className); 1653af6ab5fSopenharmony_ci return; 1663af6ab5fSopenharmony_ci } 1673af6ab5fSopenharmony_ci std::vector<std::string> funcDefinedClasses = {className}; 1683af6ab5fSopenharmony_ci funcDefinedClasses_.insert({funcName, funcDefinedClasses}); 1693af6ab5fSopenharmony_ci} 1703af6ab5fSopenharmony_ci 1713af6ab5fSopenharmony_cistd::vector<std::pair<std::string, std::string>> PatchFix::GenerateFunctionAndClassHash(panda::pandasm::Function *func, 1723af6ab5fSopenharmony_ci LiteralBuffers &literalBuffers) 1733af6ab5fSopenharmony_ci{ 1743af6ab5fSopenharmony_ci std::stringstream ss; 1753af6ab5fSopenharmony_ci std::vector<std::pair<std::string, std::string>> hashList; 1763af6ab5fSopenharmony_ci 1773af6ab5fSopenharmony_ci ss << ".function any " << func->name << '('; 1783af6ab5fSopenharmony_ci 1793af6ab5fSopenharmony_ci for (uint32_t i = 0; i < func->GetParamsNum(); i++) { 1803af6ab5fSopenharmony_ci ss << "any a" << std::to_string(i); 1813af6ab5fSopenharmony_ci if (i != func->GetParamsNum() - 1) { 1823af6ab5fSopenharmony_ci ss << ", "; 1833af6ab5fSopenharmony_ci } 1843af6ab5fSopenharmony_ci } 1853af6ab5fSopenharmony_ci ss << ") {" << std::endl; 1863af6ab5fSopenharmony_ci 1873af6ab5fSopenharmony_ci for (const auto &ins : func->ins) { 1883af6ab5fSopenharmony_ci ss << (ins.set_label ? "" : "\t") << ins.ToString("", true, func->GetTotalRegs()) << " "; 1893af6ab5fSopenharmony_ci if (ins.opcode == panda::pandasm::Opcode::CREATEARRAYWITHBUFFER || 1903af6ab5fSopenharmony_ci ins.opcode == panda::pandasm::Opcode::CREATEOBJECTWITHBUFFER) { 1913af6ab5fSopenharmony_ci int64_t bufferIdx = GetLiteralIdxFromStringId(ins.ids[0]); 1923af6ab5fSopenharmony_ci ss << ExpandLiteral(bufferIdx, literalBuffers) << " "; 1933af6ab5fSopenharmony_ci } else if (ins.opcode == panda::pandasm::Opcode::DEFINECLASSWITHBUFFER) { 1943af6ab5fSopenharmony_ci CollectFunctionsWithDefinedClasses(func->name, ins.ids[0]); 1953af6ab5fSopenharmony_ci int64_t bufferIdx = GetLiteralIdxFromStringId(ins.ids[1]); 1963af6ab5fSopenharmony_ci std::string literalStr = ExpandLiteral(bufferIdx, literalBuffers); 1973af6ab5fSopenharmony_ci auto classHash = Helpers::GetHashString(literalStr); 1983af6ab5fSopenharmony_ci hashList.push_back(std::pair<std::string, std::string>(ins.ids[0], classHash)); 1993af6ab5fSopenharmony_ci CollectClassMemberFunctions(ins.ids[0], bufferIdx, literalBuffers); 2003af6ab5fSopenharmony_ci } 2013af6ab5fSopenharmony_ci ss << " "; 2023af6ab5fSopenharmony_ci } 2033af6ab5fSopenharmony_ci 2043af6ab5fSopenharmony_ci ss << "}" << std::endl; 2053af6ab5fSopenharmony_ci 2063af6ab5fSopenharmony_ci for (const auto &ct : func->catch_blocks) { 2073af6ab5fSopenharmony_ci ss << ".catchall " << ct.try_begin_label << ", " << ct.try_end_label << ", " << ct.catch_begin_label 2083af6ab5fSopenharmony_ci << std::endl; 2093af6ab5fSopenharmony_ci } 2103af6ab5fSopenharmony_ci 2113af6ab5fSopenharmony_ci auto funcHash = Helpers::GetHashString(ss.str()); 2123af6ab5fSopenharmony_ci hashList.push_back(std::pair<std::string, std::string>(func->name, funcHash)); 2133af6ab5fSopenharmony_ci return hashList; 2143af6ab5fSopenharmony_ci} 2153af6ab5fSopenharmony_ci 2163af6ab5fSopenharmony_cistd::string PatchFix::ConvertLiteralToString(std::vector<panda::pandasm::LiteralArray::Literal> &literalBuffer) 2173af6ab5fSopenharmony_ci{ 2183af6ab5fSopenharmony_ci std::stringstream ss; 2193af6ab5fSopenharmony_ci int count = 0; 2203af6ab5fSopenharmony_ci for (auto &literal : literalBuffer) { 2213af6ab5fSopenharmony_ci ss << "{" << "index: " << count++ << " "; 2223af6ab5fSopenharmony_ci ss << "tag: " << static_cast<std::underlying_type<panda::es2panda::ir::LiteralTag>::type>(literal.tag_); 2233af6ab5fSopenharmony_ci ss << " "; 2243af6ab5fSopenharmony_ci std::string val; 2253af6ab5fSopenharmony_ci std::visit([&val](auto&& element) { 2263af6ab5fSopenharmony_ci val += "val: "; 2273af6ab5fSopenharmony_ci val += element; 2283af6ab5fSopenharmony_ci val += " "; 2293af6ab5fSopenharmony_ci }, literal.value_); 2303af6ab5fSopenharmony_ci ss << val; 2313af6ab5fSopenharmony_ci ss << "},"; 2323af6ab5fSopenharmony_ci } 2333af6ab5fSopenharmony_ci 2343af6ab5fSopenharmony_ci return ss.str(); 2353af6ab5fSopenharmony_ci} 2363af6ab5fSopenharmony_ci 2373af6ab5fSopenharmony_cistd::string PatchFix::ExpandLiteral(int64_t bufferIdx, PatchFix::LiteralBuffers &literalBuffers) 2383af6ab5fSopenharmony_ci{ 2393af6ab5fSopenharmony_ci for (auto &litPair : literalBuffers) { 2403af6ab5fSopenharmony_ci if (litPair.first == bufferIdx) { 2413af6ab5fSopenharmony_ci return ConvertLiteralToString(litPair.second); 2423af6ab5fSopenharmony_ci } 2433af6ab5fSopenharmony_ci } 2443af6ab5fSopenharmony_ci 2453af6ab5fSopenharmony_ci return ""; 2463af6ab5fSopenharmony_ci} 2473af6ab5fSopenharmony_ci 2483af6ab5fSopenharmony_cistd::vector<std::string> PatchFix::GetLiteralMethods(int64_t bufferIdx, PatchFix::LiteralBuffers &literalBuffers) 2493af6ab5fSopenharmony_ci{ 2503af6ab5fSopenharmony_ci std::vector<std::string> methods; 2513af6ab5fSopenharmony_ci for (auto &litPair : literalBuffers) { 2523af6ab5fSopenharmony_ci if (litPair.first != bufferIdx) { 2533af6ab5fSopenharmony_ci continue; 2543af6ab5fSopenharmony_ci } 2553af6ab5fSopenharmony_ci for (auto &literal : litPair.second) { 2563af6ab5fSopenharmony_ci switch (literal.tag_) { 2573af6ab5fSopenharmony_ci case panda::panda_file::LiteralTag::METHOD: 2583af6ab5fSopenharmony_ci case panda::panda_file::LiteralTag::GENERATORMETHOD: 2593af6ab5fSopenharmony_ci case panda::panda_file::LiteralTag::ASYNCGENERATORMETHOD: { 2603af6ab5fSopenharmony_ci methods.push_back(std::get<std::string>(literal.value_)); 2613af6ab5fSopenharmony_ci break; 2623af6ab5fSopenharmony_ci } 2633af6ab5fSopenharmony_ci default: 2643af6ab5fSopenharmony_ci break; 2653af6ab5fSopenharmony_ci } 2663af6ab5fSopenharmony_ci } 2673af6ab5fSopenharmony_ci } 2683af6ab5fSopenharmony_ci 2693af6ab5fSopenharmony_ci return methods; 2703af6ab5fSopenharmony_ci} 2713af6ab5fSopenharmony_ci 2723af6ab5fSopenharmony_civoid PatchFix::CollectClassMemberFunctions(const std::string &className, int64_t bufferIdx, 2733af6ab5fSopenharmony_ci PatchFix::LiteralBuffers &literalBuffers) 2743af6ab5fSopenharmony_ci{ 2753af6ab5fSopenharmony_ci std::vector<std::string> classMemberFunctions = GetLiteralMethods(bufferIdx, literalBuffers); 2763af6ab5fSopenharmony_ci classMemberFunctions.push_back(className); 2773af6ab5fSopenharmony_ci classMemberFunctions_.insert({className, classMemberFunctions}); 2783af6ab5fSopenharmony_ci} 2793af6ab5fSopenharmony_ci 2803af6ab5fSopenharmony_cibool PatchFix::IsScopeValidToPatchLexical(binder::VariableScope *scope) const 2813af6ab5fSopenharmony_ci{ 2823af6ab5fSopenharmony_ci if (IsDumpSymbolTable()) { 2833af6ab5fSopenharmony_ci return false; 2843af6ab5fSopenharmony_ci } 2853af6ab5fSopenharmony_ci 2863af6ab5fSopenharmony_ci CHECK_NOT_NULL(scope); 2873af6ab5fSopenharmony_ci if (!scope->IsFunctionVariableScope()) { 2883af6ab5fSopenharmony_ci return false; 2893af6ab5fSopenharmony_ci } 2903af6ab5fSopenharmony_ci 2913af6ab5fSopenharmony_ci auto funcName = scope->AsFunctionVariableScope()->InternalName(); 2923af6ab5fSopenharmony_ci if (std::string(funcName) != funcMain0_) { 2933af6ab5fSopenharmony_ci return false; 2943af6ab5fSopenharmony_ci } 2953af6ab5fSopenharmony_ci return true; 2963af6ab5fSopenharmony_ci} 2973af6ab5fSopenharmony_ci 2983af6ab5fSopenharmony_civoid PatchFix::AllocSlotfromPatchEnv(const std::string &variableName) 2993af6ab5fSopenharmony_ci{ 3003af6ab5fSopenharmony_ci if (!topScopeLexEnvs_.count(variableName)) { 3013af6ab5fSopenharmony_ci topScopeLexEnvs_[variableName] = topScopeIdx_++; 3023af6ab5fSopenharmony_ci } 3033af6ab5fSopenharmony_ci} 3043af6ab5fSopenharmony_ci 3053af6ab5fSopenharmony_ciuint32_t PatchFix::GetSlotIdFromSymbolTable(const std::string &variableName) 3063af6ab5fSopenharmony_ci{ 3073af6ab5fSopenharmony_ci auto functionIter = originFunctionInfo_->find(funcMain0_); 3083af6ab5fSopenharmony_ci if (functionIter != originFunctionInfo_->end()) { 3093af6ab5fSopenharmony_ci for (const auto &lexenv : functionIter->second.lexenv) { 3103af6ab5fSopenharmony_ci if (lexenv.second.first == variableName) { 3113af6ab5fSopenharmony_ci return lexenv.first; 3123af6ab5fSopenharmony_ci } 3133af6ab5fSopenharmony_ci } 3143af6ab5fSopenharmony_ci } 3153af6ab5fSopenharmony_ci return UINT32_MAX; 3163af6ab5fSopenharmony_ci} 3173af6ab5fSopenharmony_ci 3183af6ab5fSopenharmony_ciuint32_t PatchFix::GetEnvSizeOfFuncMain0() 3193af6ab5fSopenharmony_ci{ 3203af6ab5fSopenharmony_ci auto functionIter = originFunctionInfo_->find(funcMain0_); 3213af6ab5fSopenharmony_ci ASSERT(functionIter != originFunctionInfo_->end()); 3223af6ab5fSopenharmony_ci return functionIter->second.lexenv.size(); 3233af6ab5fSopenharmony_ci} 3243af6ab5fSopenharmony_ci 3253af6ab5fSopenharmony_ciuint32_t PatchFix::GetPatchLexicalIdx(const std::string &variableName) 3263af6ab5fSopenharmony_ci{ 3273af6ab5fSopenharmony_ci ASSERT(topScopeLexEnvs_.count(variableName)); 3283af6ab5fSopenharmony_ci return topScopeLexEnvs_[variableName]; 3293af6ab5fSopenharmony_ci} 3303af6ab5fSopenharmony_ci 3313af6ab5fSopenharmony_cibool IsFunctionOrClassDefineIns(panda::pandasm::Ins &ins) 3323af6ab5fSopenharmony_ci{ 3333af6ab5fSopenharmony_ci if (ins.opcode == panda::pandasm::Opcode::DEFINEMETHOD || 3343af6ab5fSopenharmony_ci ins.opcode == panda::pandasm::Opcode::DEFINEFUNC || 3353af6ab5fSopenharmony_ci ins.opcode == panda::pandasm::Opcode::DEFINECLASSWITHBUFFER) { 3363af6ab5fSopenharmony_ci return true; 3373af6ab5fSopenharmony_ci } 3383af6ab5fSopenharmony_ci return false; 3393af6ab5fSopenharmony_ci} 3403af6ab5fSopenharmony_ci 3413af6ab5fSopenharmony_cibool IsStPatchVarIns(panda::pandasm::Ins &ins) 3423af6ab5fSopenharmony_ci{ 3433af6ab5fSopenharmony_ci return ins.opcode == panda::pandasm::Opcode::WIDE_STPATCHVAR; 3443af6ab5fSopenharmony_ci} 3453af6ab5fSopenharmony_ci 3463af6ab5fSopenharmony_civoid PatchFix::CollectFuncDefineIns(panda::pandasm::Function *func) 3473af6ab5fSopenharmony_ci{ 3483af6ab5fSopenharmony_ci for (size_t i = 0; i < func->ins.size(); ++i) { 3493af6ab5fSopenharmony_ci if (IsFunctionOrClassDefineIns(func->ins[i])) { 3503af6ab5fSopenharmony_ci funcDefineIns_.push_back(func->ins[i]); // push define ins 3513af6ab5fSopenharmony_ci funcDefineIns_.push_back(func->ins[i + 1]); // push store ins 3523af6ab5fSopenharmony_ci } 3533af6ab5fSopenharmony_ci } 3543af6ab5fSopenharmony_ci} 3553af6ab5fSopenharmony_ci 3563af6ab5fSopenharmony_civoid PatchFix::HandleModifiedClasses(panda::pandasm::Program *prog) 3573af6ab5fSopenharmony_ci{ 3583af6ab5fSopenharmony_ci for (auto &cls: classMemberFunctions_) { 3593af6ab5fSopenharmony_ci for (auto &func: cls.second) { 3603af6ab5fSopenharmony_ci if (!prog->function_table.at(func).metadata->IsForeign()) { 3613af6ab5fSopenharmony_ci modifiedClassNames_.insert(cls.first); 3623af6ab5fSopenharmony_ci break; 3633af6ab5fSopenharmony_ci } 3643af6ab5fSopenharmony_ci } 3653af6ab5fSopenharmony_ci } 3663af6ab5fSopenharmony_ci 3673af6ab5fSopenharmony_ci for (auto &cls: modifiedClassNames_) { 3683af6ab5fSopenharmony_ci auto &memberFunctions = classMemberFunctions_[cls]; 3693af6ab5fSopenharmony_ci for (auto &func: memberFunctions) { 3703af6ab5fSopenharmony_ci if (prog->function_table.at(func).metadata->IsForeign()) { 3713af6ab5fSopenharmony_ci prog->function_table.at(func).metadata->RemoveAttribute(EXTERNAL_ATTRIBUTE); 3723af6ab5fSopenharmony_ci } 3733af6ab5fSopenharmony_ci } 3743af6ab5fSopenharmony_ci } 3753af6ab5fSopenharmony_ci} 3763af6ab5fSopenharmony_ci 3773af6ab5fSopenharmony_civoid PatchFix::HandleModifiedDefinedClassFunc(panda::pandasm::Program *prog) 3783af6ab5fSopenharmony_ci{ 3793af6ab5fSopenharmony_ci for (auto &funcInfo: funcDefinedClasses_) { 3803af6ab5fSopenharmony_ci for (auto &definedClass: funcInfo.second) { 3813af6ab5fSopenharmony_ci if (modifiedClassNames_.count(definedClass) && 3823af6ab5fSopenharmony_ci prog->function_table.at(funcInfo.first).metadata->IsForeign()) { 3833af6ab5fSopenharmony_ci prog->function_table.at(funcInfo.first).metadata->RemoveAttribute(EXTERNAL_ATTRIBUTE); 3843af6ab5fSopenharmony_ci } 3853af6ab5fSopenharmony_ci } 3863af6ab5fSopenharmony_ci } 3873af6ab5fSopenharmony_ci} 3883af6ab5fSopenharmony_ci 3893af6ab5fSopenharmony_civoid PatchFix::AddHeadAndTailInsForPatchFuncMain0(std::vector<panda::pandasm::Ins> &ins) 3903af6ab5fSopenharmony_ci{ 3913af6ab5fSopenharmony_ci panda::pandasm::Ins returnUndefine; 3923af6ab5fSopenharmony_ci returnUndefine.opcode = pandasm::Opcode::RETURNUNDEFINED; 3933af6ab5fSopenharmony_ci 3943af6ab5fSopenharmony_ci if (ins.size() == 0) { 3953af6ab5fSopenharmony_ci ins.push_back(returnUndefine); 3963af6ab5fSopenharmony_ci return; 3973af6ab5fSopenharmony_ci } 3983af6ab5fSopenharmony_ci 3993af6ab5fSopenharmony_ci panda::pandasm::Ins newLexenv; 4003af6ab5fSopenharmony_ci newLexenv.opcode = pandasm::Opcode::NEWLEXENV; 4013af6ab5fSopenharmony_ci newLexenv.imms.reserve(1); 4023af6ab5fSopenharmony_ci auto newFuncNum = long(ins.size() / 2); // each new function has 2 ins: define and store 4033af6ab5fSopenharmony_ci newLexenv.imms.emplace_back(newFuncNum); 4043af6ab5fSopenharmony_ci 4053af6ab5fSopenharmony_ci ins.insert(ins.begin(), newLexenv); 4063af6ab5fSopenharmony_ci ins.push_back(returnUndefine); 4073af6ab5fSopenharmony_ci} 4083af6ab5fSopenharmony_ci 4093af6ab5fSopenharmony_civoid PatchFix::AddTailInsForPatchFuncMain1(std::vector<panda::pandasm::Ins> &ins) 4103af6ab5fSopenharmony_ci{ 4113af6ab5fSopenharmony_ci panda::pandasm::Ins returnUndefined; 4123af6ab5fSopenharmony_ci returnUndefined.opcode = pandasm::Opcode::RETURNUNDEFINED; 4133af6ab5fSopenharmony_ci ins.push_back(returnUndefined); 4143af6ab5fSopenharmony_ci} 4153af6ab5fSopenharmony_ci 4163af6ab5fSopenharmony_civoid PatchFix::CreateFunctionPatchMain0AndMain1(panda::pandasm::Function &patchFuncMain0, 4173af6ab5fSopenharmony_ci panda::pandasm::Function &patchFuncMain1) 4183af6ab5fSopenharmony_ci{ 4193af6ab5fSopenharmony_ci const size_t defaultParamCount = 3; 4203af6ab5fSopenharmony_ci patchFuncMain0.params.reserve(defaultParamCount); 4213af6ab5fSopenharmony_ci patchFuncMain1.params.reserve(defaultParamCount); 4223af6ab5fSopenharmony_ci for (uint32_t i = 0; i < defaultParamCount; ++i) { 4233af6ab5fSopenharmony_ci patchFuncMain0.params.emplace_back(panda::pandasm::Type("any", 0), SRC_LANG); 4243af6ab5fSopenharmony_ci patchFuncMain1.params.emplace_back(panda::pandasm::Type("any", 0), SRC_LANG); 4253af6ab5fSopenharmony_ci } 4263af6ab5fSopenharmony_ci 4273af6ab5fSopenharmony_ci std::vector<panda::pandasm::Ins> patchMain0DefineIns; 4283af6ab5fSopenharmony_ci std::vector<panda::pandasm::Ins> patchMain1DefineIns; 4293af6ab5fSopenharmony_ci 4303af6ab5fSopenharmony_ci for (size_t i = 0; i < funcDefineIns_.size(); ++i) { 4313af6ab5fSopenharmony_ci if (IsFunctionOrClassDefineIns(funcDefineIns_[i])) { 4323af6ab5fSopenharmony_ci auto &name = funcDefineIns_[i].ids[0]; 4333af6ab5fSopenharmony_ci if (newFuncNames_.count(name) && IsStPatchVarIns(funcDefineIns_[i + 1])) { 4343af6ab5fSopenharmony_ci patchMain0DefineIns.push_back(funcDefineIns_[i]); 4353af6ab5fSopenharmony_ci patchMain0DefineIns.push_back(funcDefineIns_[i + 1]); 4363af6ab5fSopenharmony_ci continue; 4373af6ab5fSopenharmony_ci } 4383af6ab5fSopenharmony_ci if (patchFuncNames_.count(name) || modifiedClassNames_.count(name)) { 4393af6ab5fSopenharmony_ci patchMain1DefineIns.push_back(funcDefineIns_[i]); 4403af6ab5fSopenharmony_ci continue; 4413af6ab5fSopenharmony_ci } 4423af6ab5fSopenharmony_ci } 4433af6ab5fSopenharmony_ci } 4443af6ab5fSopenharmony_ci 4453af6ab5fSopenharmony_ci AddHeadAndTailInsForPatchFuncMain0(patchMain0DefineIns); 4463af6ab5fSopenharmony_ci AddTailInsForPatchFuncMain1(patchMain1DefineIns); 4473af6ab5fSopenharmony_ci 4483af6ab5fSopenharmony_ci patchFuncMain0.ins = patchMain0DefineIns; 4493af6ab5fSopenharmony_ci patchFuncMain1.ins = patchMain1DefineIns; 4503af6ab5fSopenharmony_ci 4513af6ab5fSopenharmony_ci patchFuncMain0.return_type = panda::pandasm::Type("any", 0); 4523af6ab5fSopenharmony_ci patchFuncMain1.return_type = panda::pandasm::Type("any", 0); 4533af6ab5fSopenharmony_ci} 4543af6ab5fSopenharmony_ci 4553af6ab5fSopenharmony_civoid PatchFix::Finalize(panda::pandasm::Program **prog) 4563af6ab5fSopenharmony_ci{ 4573af6ab5fSopenharmony_ci if (IsDumpSymbolTable() || IsColdReload()) { 4583af6ab5fSopenharmony_ci return; 4593af6ab5fSopenharmony_ci } 4603af6ab5fSopenharmony_ci 4613af6ab5fSopenharmony_ci HandleModifiedClasses(*prog); 4623af6ab5fSopenharmony_ci 4633af6ab5fSopenharmony_ci HandleModifiedDefinedClassFunc(*prog); 4643af6ab5fSopenharmony_ci 4653af6ab5fSopenharmony_ci if (patchError_) { 4663af6ab5fSopenharmony_ci *prog = nullptr; 4673af6ab5fSopenharmony_ci std::cerr << "[Patch] Found unsupported change in file, will not generate patch!" << std::endl; 4683af6ab5fSopenharmony_ci return; 4693af6ab5fSopenharmony_ci } 4703af6ab5fSopenharmony_ci 4713af6ab5fSopenharmony_ci if (IsHotReload() || IsColdFix()) { 4723af6ab5fSopenharmony_ci return; 4733af6ab5fSopenharmony_ci } 4743af6ab5fSopenharmony_ci 4753af6ab5fSopenharmony_ci panda::pandasm::Function patchFuncMain0(patchMain0_, SRC_LANG); 4763af6ab5fSopenharmony_ci panda::pandasm::Function patchFuncMain1(patchMain1_, SRC_LANG); 4773af6ab5fSopenharmony_ci CreateFunctionPatchMain0AndMain1(patchFuncMain0, patchFuncMain1); 4783af6ab5fSopenharmony_ci 4793af6ab5fSopenharmony_ci (*prog)->function_table.emplace(patchFuncMain0.name, std::move(patchFuncMain0)); 4803af6ab5fSopenharmony_ci (*prog)->function_table.emplace(patchFuncMain1.name, std::move(patchFuncMain1)); 4813af6ab5fSopenharmony_ci} 4823af6ab5fSopenharmony_ci 4833af6ab5fSopenharmony_cibool PatchFix::CompareLexenv(const std::string &funcName, const compiler::PandaGen *pg, 4843af6ab5fSopenharmony_ci SymbolTable::OriginFunctionInfo &bytecodeInfo) 4853af6ab5fSopenharmony_ci{ 4863af6ab5fSopenharmony_ci auto &lexicalVarNameAndTypes = pg->TopScope()->GetLexicalVarNameAndTypes(); 4873af6ab5fSopenharmony_ci auto &lexenv = bytecodeInfo.lexenv; 4883af6ab5fSopenharmony_ci if (funcName != funcMain0_) { 4893af6ab5fSopenharmony_ci if (lexenv.size() != lexicalVarNameAndTypes.size()) { 4903af6ab5fSopenharmony_ci std::cerr << "[Patch] Found lexical variable added or removed in " << funcName << ", not supported!" 4913af6ab5fSopenharmony_ci << std::endl; 4923af6ab5fSopenharmony_ci patchError_ = true; 4933af6ab5fSopenharmony_ci return false; 4943af6ab5fSopenharmony_ci } 4953af6ab5fSopenharmony_ci for (auto &variable: lexicalVarNameAndTypes) { 4963af6ab5fSopenharmony_ci auto varSlot = variable.first; 4973af6ab5fSopenharmony_ci auto lexenvIter = lexenv.find(varSlot); 4983af6ab5fSopenharmony_ci if (lexenvIter == lexenv.end()) { 4993af6ab5fSopenharmony_ci std::cerr << "[Patch] Found new lexical variable added in function " << funcName << ", not supported!" 5003af6ab5fSopenharmony_ci << std::endl; 5013af6ab5fSopenharmony_ci patchError_ = true; 5023af6ab5fSopenharmony_ci return false; 5033af6ab5fSopenharmony_ci } 5043af6ab5fSopenharmony_ci 5053af6ab5fSopenharmony_ci auto &lexInfo = lexenvIter->second; 5063af6ab5fSopenharmony_ci if (!IsColdFix() && (std::string(variable.second.first) != lexInfo.first || 5073af6ab5fSopenharmony_ci variable.second.second != lexInfo.second)) { 5083af6ab5fSopenharmony_ci std::cerr << "[Patch] Found lexical variable changed in function " << funcName << ", not supported!" 5093af6ab5fSopenharmony_ci << std::endl; 5103af6ab5fSopenharmony_ci patchError_ = true; 5113af6ab5fSopenharmony_ci return false; 5123af6ab5fSopenharmony_ci } 5133af6ab5fSopenharmony_ci } 5143af6ab5fSopenharmony_ci } 5153af6ab5fSopenharmony_ci return true; 5163af6ab5fSopenharmony_ci} 5173af6ab5fSopenharmony_ci 5183af6ab5fSopenharmony_cibool PatchFix::CompareClassHash(std::vector<std::pair<std::string, std::string>> &hashList, 5193af6ab5fSopenharmony_ci SymbolTable::OriginFunctionInfo &bytecodeInfo) 5203af6ab5fSopenharmony_ci{ 5213af6ab5fSopenharmony_ci auto &classInfo = bytecodeInfo.classHash; 5223af6ab5fSopenharmony_ci for (size_t i = 0; i < hashList.size() - 1; ++i) { 5233af6ab5fSopenharmony_ci auto &className = hashList[i].first; 5243af6ab5fSopenharmony_ci auto classIter = classInfo.find(className); 5253af6ab5fSopenharmony_ci if (!IsHotReload() && classIter != classInfo.end() && classIter->second != hashList[i].second) { 5263af6ab5fSopenharmony_ci if (IsColdFix()) { 5273af6ab5fSopenharmony_ci modifiedClassNames_.insert(className); 5283af6ab5fSopenharmony_ci continue; 5293af6ab5fSopenharmony_ci } else { 5303af6ab5fSopenharmony_ci ASSERT(IsHotFix()); 5313af6ab5fSopenharmony_ci std::cerr << "[Patch] Found class " << hashList[i].first << " changed, not supported!" << std::endl; 5323af6ab5fSopenharmony_ci } 5333af6ab5fSopenharmony_ci patchError_ = true; 5343af6ab5fSopenharmony_ci return false; 5353af6ab5fSopenharmony_ci } 5363af6ab5fSopenharmony_ci } 5373af6ab5fSopenharmony_ci return true; 5383af6ab5fSopenharmony_ci} 5393af6ab5fSopenharmony_ci 5403af6ab5fSopenharmony_civoid PatchFix::CheckAndRestoreSpecialFunctionName(uint32_t globalIndexForSpecialFunc, std::string &funcInternalName, 5413af6ab5fSopenharmony_ci std::string recordName) 5423af6ab5fSopenharmony_ci{ 5433af6ab5fSopenharmony_ci auto it = originRecordHashFunctionNames_->find(recordName); 5443af6ab5fSopenharmony_ci if (it != originRecordHashFunctionNames_->end()) { 5453af6ab5fSopenharmony_ci if (it->second.size() == 0 || globalIndexForSpecialFunc > it->second.size()) { 5463af6ab5fSopenharmony_ci // anonymous, special or duplicate function added 5473af6ab5fSopenharmony_ci std::cerr << "[Patch] Found new anonymous, special(containing '.' or '\\') or duplicate name function " 5483af6ab5fSopenharmony_ci << funcInternalName << " not supported!" << std::endl; 5493af6ab5fSopenharmony_ci patchError_ = true; 5503af6ab5fSopenharmony_ci return; 5513af6ab5fSopenharmony_ci } 5523af6ab5fSopenharmony_ci std::string originalName = it->second.at(std::to_string(globalIndexForSpecialFunc)); 5533af6ab5fSopenharmony_ci // special name function in the same position must have the same real function name as original 5543af6ab5fSopenharmony_ci if (originalName.substr(originalName.find_last_of("#")) != 5553af6ab5fSopenharmony_ci funcInternalName.substr(funcInternalName.find_last_of("#"))) { 5563af6ab5fSopenharmony_ci std::cerr << "[Patch] Found new anonymous, special(containing '.' or '\\') or duplicate name function " 5573af6ab5fSopenharmony_ci << funcInternalName << " not supported!" << std::endl; 5583af6ab5fSopenharmony_ci patchError_ = true; 5593af6ab5fSopenharmony_ci return; 5603af6ab5fSopenharmony_ci } 5613af6ab5fSopenharmony_ci funcInternalName = originalName; 5623af6ab5fSopenharmony_ci } 5633af6ab5fSopenharmony_ci} 5643af6ab5fSopenharmony_ci 5653af6ab5fSopenharmony_civoid PatchFix::HandleFunction(const compiler::PandaGen *pg, panda::pandasm::Function *func, 5663af6ab5fSopenharmony_ci LiteralBuffers &literalBuffers) 5673af6ab5fSopenharmony_ci{ 5683af6ab5fSopenharmony_ci std::string funcName = func->name; 5693af6ab5fSopenharmony_ci auto originFunction = originFunctionInfo_->find(funcName); 5703af6ab5fSopenharmony_ci if (originFunction == originFunctionInfo_->end()) { 5713af6ab5fSopenharmony_ci if ((!util::Helpers::IsDefaultApiVersion(targetApiVersion_, targetApiSubVersion_)) && 5723af6ab5fSopenharmony_ci IsHotFix() && 5733af6ab5fSopenharmony_ci IsAnonymousOrSpecialOrDuplicateFunction(funcName)) { 5743af6ab5fSopenharmony_ci std::cerr << "[Patch] Found new anonymous, special(containing '.' or '\\') or duplicate name function " 5753af6ab5fSopenharmony_ci << funcName << " not supported!" << std::endl; 5763af6ab5fSopenharmony_ci patchError_ = true; 5773af6ab5fSopenharmony_ci return; 5783af6ab5fSopenharmony_ci } 5793af6ab5fSopenharmony_ci newFuncNames_.insert(funcName); 5803af6ab5fSopenharmony_ci CollectFuncDefineIns(func); 5813af6ab5fSopenharmony_ci return; 5823af6ab5fSopenharmony_ci } 5833af6ab5fSopenharmony_ci 5843af6ab5fSopenharmony_ci auto &bytecodeInfo = originFunction->second; 5853af6ab5fSopenharmony_ci if (!CompareLexenv(funcName, pg, bytecodeInfo)) { 5863af6ab5fSopenharmony_ci return; 5873af6ab5fSopenharmony_ci } 5883af6ab5fSopenharmony_ci 5893af6ab5fSopenharmony_ci auto hashList = GenerateFunctionAndClassHash(func, literalBuffers); 5903af6ab5fSopenharmony_ci if (!CompareClassHash(hashList, bytecodeInfo)) { 5913af6ab5fSopenharmony_ci return; 5923af6ab5fSopenharmony_ci } 5933af6ab5fSopenharmony_ci 5943af6ab5fSopenharmony_ci if (IsHotReload()) { 5953af6ab5fSopenharmony_ci return; 5963af6ab5fSopenharmony_ci } 5973af6ab5fSopenharmony_ci 5983af6ab5fSopenharmony_ci auto funcHash = hashList.back().second; 5993af6ab5fSopenharmony_ci 6003af6ab5fSopenharmony_ci if (funcName == funcMain0_) { 6013af6ab5fSopenharmony_ci if (IsHotFix()) { 6023af6ab5fSopenharmony_ci func->metadata->SetAttribute(EXTERNAL_ATTRIBUTE); 6033af6ab5fSopenharmony_ci } else { 6043af6ab5fSopenharmony_ci patchFuncNames_.insert(funcName); 6053af6ab5fSopenharmony_ci } 6063af6ab5fSopenharmony_ci } else { 6073af6ab5fSopenharmony_ci if (funcHash == bytecodeInfo.funcHash) { 6083af6ab5fSopenharmony_ci func->metadata->SetAttribute(EXTERNAL_ATTRIBUTE); 6093af6ab5fSopenharmony_ci } else { 6103af6ab5fSopenharmony_ci patchFuncNames_.insert(funcName); 6113af6ab5fSopenharmony_ci } 6123af6ab5fSopenharmony_ci } 6133af6ab5fSopenharmony_ci 6143af6ab5fSopenharmony_ci CollectFuncDefineIns(func); 6153af6ab5fSopenharmony_ci} 6163af6ab5fSopenharmony_ci 6173af6ab5fSopenharmony_civoid PatchFix::DumpFunctionInfo(const compiler::PandaGen *pg, panda::pandasm::Function *func, 6183af6ab5fSopenharmony_ci PatchFix::LiteralBuffers &literalBuffers) 6193af6ab5fSopenharmony_ci{ 6203af6ab5fSopenharmony_ci std::stringstream ss; 6213af6ab5fSopenharmony_ci 6223af6ab5fSopenharmony_ci ss << pg->InternalName(); 6233af6ab5fSopenharmony_ci ss << SymbolTable::SECOND_LEVEL_SEPERATOR << pg->InternalName() << SymbolTable::SECOND_LEVEL_SEPERATOR; 6243af6ab5fSopenharmony_ci 6253af6ab5fSopenharmony_ci std::vector<std::pair<std::string, std::string>> hashList = GenerateFunctionAndClassHash(func, literalBuffers); 6263af6ab5fSopenharmony_ci ss << hashList.back().second << SymbolTable::SECOND_LEVEL_SEPERATOR; 6273af6ab5fSopenharmony_ci 6283af6ab5fSopenharmony_ci if (util::Helpers::IsDefaultApiVersion(targetApiVersion_, targetApiSubVersion_)) { 6293af6ab5fSopenharmony_ci auto internalNameStr = pg->InternalName().Mutf8(); 6303af6ab5fSopenharmony_ci if (internalNameStr.find("#") != std::string::npos) { 6313af6ab5fSopenharmony_ci ss << (pg->Binder()->SpecialFuncNameIndexMap()).at(internalNameStr) << SymbolTable::SECOND_LEVEL_SEPERATOR; 6323af6ab5fSopenharmony_ci } else { 6333af6ab5fSopenharmony_ci // index 0 for all the normal name functions 6343af6ab5fSopenharmony_ci ss << "0" << SymbolTable::SECOND_LEVEL_SEPERATOR; 6353af6ab5fSopenharmony_ci } 6363af6ab5fSopenharmony_ci } 6373af6ab5fSopenharmony_ci 6383af6ab5fSopenharmony_ci ss << SymbolTable::FIRST_LEVEL_SEPERATOR; 6393af6ab5fSopenharmony_ci for (size_t i = 0; i < hashList.size() - 1; ++i) { 6403af6ab5fSopenharmony_ci ss << hashList[i].first << SymbolTable::SECOND_LEVEL_SEPERATOR << hashList[i].second << 6413af6ab5fSopenharmony_ci SymbolTable::SECOND_LEVEL_SEPERATOR; 6423af6ab5fSopenharmony_ci } 6433af6ab5fSopenharmony_ci ss << SymbolTable::SECOND_LEVEL_SEPERATOR << SymbolTable::FIRST_LEVEL_SEPERATOR; 6443af6ab5fSopenharmony_ci 6453af6ab5fSopenharmony_ci for (auto &variable: pg->TopScope()->GetLexicalVarNameAndTypes()) { 6463af6ab5fSopenharmony_ci ss << variable.second.first << SymbolTable::SECOND_LEVEL_SEPERATOR 6473af6ab5fSopenharmony_ci << variable.first << SymbolTable::SECOND_LEVEL_SEPERATOR 6483af6ab5fSopenharmony_ci << variable.second.second << SymbolTable::SECOND_LEVEL_SEPERATOR; 6493af6ab5fSopenharmony_ci } 6503af6ab5fSopenharmony_ci ss << SymbolTable::SECOND_LEVEL_SEPERATOR << std::endl; 6513af6ab5fSopenharmony_ci 6523af6ab5fSopenharmony_ci symbolTable_->FillSymbolTable(ss); 6533af6ab5fSopenharmony_ci} 6543af6ab5fSopenharmony_ci 6553af6ab5fSopenharmony_cibool PatchFix::IsAdditionalVarInPatch(uint32_t slot) 6563af6ab5fSopenharmony_ci{ 6573af6ab5fSopenharmony_ci return slot == UINT32_MAX; 6583af6ab5fSopenharmony_ci} 6593af6ab5fSopenharmony_ci 6603af6ab5fSopenharmony_cibool PatchFix::IsDumpSymbolTable() const 6613af6ab5fSopenharmony_ci{ 6623af6ab5fSopenharmony_ci return patchFixKind_ == PatchFixKind::DUMPSYMBOLTABLE; 6633af6ab5fSopenharmony_ci} 6643af6ab5fSopenharmony_ci 6653af6ab5fSopenharmony_cibool PatchFix::IsHotFix() const 6663af6ab5fSopenharmony_ci{ 6673af6ab5fSopenharmony_ci return patchFixKind_ == PatchFixKind::HOTFIX; 6683af6ab5fSopenharmony_ci} 6693af6ab5fSopenharmony_ci 6703af6ab5fSopenharmony_cibool PatchFix::IsColdFix() const 6713af6ab5fSopenharmony_ci{ 6723af6ab5fSopenharmony_ci return patchFixKind_ == PatchFixKind::COLDFIX; 6733af6ab5fSopenharmony_ci} 6743af6ab5fSopenharmony_ci 6753af6ab5fSopenharmony_cibool PatchFix::IsHotReload() const 6763af6ab5fSopenharmony_ci{ 6773af6ab5fSopenharmony_ci return patchFixKind_ == PatchFixKind::HOTRELOAD; 6783af6ab5fSopenharmony_ci} 6793af6ab5fSopenharmony_ci 6803af6ab5fSopenharmony_cibool PatchFix::IsColdReload() const 6813af6ab5fSopenharmony_ci{ 6823af6ab5fSopenharmony_ci return patchFixKind_ == PatchFixKind::COLDRELOAD; 6833af6ab5fSopenharmony_ci} 6843af6ab5fSopenharmony_ci 6853af6ab5fSopenharmony_ci} // namespace panda::es2panda::util 686