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