• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef ES2PANDA_UTIL_PATCHFIX_H
17 #define ES2PANDA_UTIL_PATCHFIX_H
18 
19 #include <assembly-function.h>
20 #include <assembly-ins.h>
21 #include <assembly-literals.h>
22 #include <assembly-program.h>
23 #include <libpandabase/utils/arena_containers.h>
24 #include <util/helpers.h>
25 #include <util/symbolTable.h>
26 
27 #include <mutex>
28 
29 namespace panda::es2panda::binder {
30 class VariableScope;
31 }  // namespace panda::es2panda::binder
32 
33 namespace panda::es2panda::compiler {
34 class PandaGen;
35 }  // namespace panda::es2panda::compiler
36 
37 namespace panda::es2panda::util {
38 
39 enum class PatchFixKind { DUMPSYMBOLTABLE, HOTFIX, COLDFIX, HOTRELOAD };
40 
41 class PatchFix {
42     using LiteralBuffers = ArenaVector<std::pair<int32_t, std::vector<panda::pandasm::LiteralArray::Literal>>>;
43 
44 public:
PatchFix(bool generateSymbolFile,bool generatePatch,PatchFixKind patchFixKind,const std::string & recordName,util::SymbolTable * symbolTable)45     PatchFix(bool generateSymbolFile, bool generatePatch, PatchFixKind patchFixKind, const std::string &recordName,
46         util::SymbolTable *symbolTable)
47         : generateSymbolFile_(generateSymbolFile), generatePatch_(generatePatch), patchFixKind_(patchFixKind),
48         recordName_(recordName),
49         symbolTable_(symbolTable),
50         allocator_(SpaceType::SPACE_TYPE_COMPILER, nullptr, true),
51         topScopeLexEnvs_(allocator_.Adapter()),
52         patchFuncNames_(allocator_.Adapter()),
53         newFuncNames_(allocator_.Adapter()),
54         funcDefineIns_(allocator_.Adapter()),
55         modifiedClassNames_(allocator_.Adapter()),
56         classMemberFunctions_(allocator_.Adapter()),
57         funcDefinedClasses_(allocator_.Adapter()) {
58             originFunctionInfo_ = symbolTable_->GetOriginFunctionInfo();
59             originModuleInfo_ = symbolTable_->GetOriginModuleInfo();
60             originRecordHashFunctionNames_ = symbolTable_->GetOriginRecordHashFunctionNames();
61             patchMain0_ = recordName_ + ".patch_main_0";
62             patchMain1_ = recordName_ + ".patch_main_1";
63             funcMain0_ = recordName_ + ".func_main_0";
64         }
65 
66     void Finalize(panda::pandasm::Program **prog);
67     bool IsScopeValidToPatchLexical(binder::VariableScope *scope) const;
68     uint32_t GetSlotIdFromSymbolTable(const std::string &variableName);
69     void AllocSlotfromPatchEnv(const std::string &variableName);
70     uint32_t GetPatchLexicalIdx(const std::string &variableName);
71     bool IsPatchVar(uint32_t slot);
72     void ProcessFunction(const compiler::PandaGen *pg, panda::pandasm::Function *func, LiteralBuffers &literalBuffers);
73     void ProcessModule(const std::string &recordName, std::vector<panda::pandasm::LiteralArray::Literal> &moduleBuffer);
74     void ProcessJsonContentRecord(const std::string &recordName, const std::string &jsonFileContent);
75     void CheckAndRestoreSpecialFunctionName(uint32_t globalIndexForSpecialFunc, std::string &funcName,
76         std::string recordName);
77     bool IsDumpSymbolTable() const;
78     bool IsHotFix() const;
79     bool IsColdFix() const;
80     bool IsHotReload() const;
81 
82 private:
83     void DumpFunctionInfo(const compiler::PandaGen *pg, panda::pandasm::Function *func, LiteralBuffers &literalBuffers);
84     void HandleFunction(const compiler::PandaGen *pg, panda::pandasm::Function *func, LiteralBuffers &literalBuffers);
85     void CollectFunctionsWithDefinedClasses(std::string funcName, std::string className);
86     std::vector<std::pair<std::string, std::string>> GenerateFunctionAndClassHash(panda::pandasm::Function *func,
87         LiteralBuffers &literalBuffers);
88     void DumpModuleInfo(const std::string &recordName,
89         std::vector<panda::pandasm::LiteralArray::Literal> &moduleBuffer);
90     void ValidateModuleInfo(const std::string &recordName,
91         std::vector<panda::pandasm::LiteralArray::Literal> &moduleBuffer);
92     void DumpJsonContentRecInfo(const std::string &recordName, const std::string &jsonFileContent);
93     void ValidateJsonContentRecInfo(const std::string &recordName, const std::string &jsonFileContent);
94 
95     std::string ExpandLiteral(int64_t bufferIdx, LiteralBuffers &literalBuffers);
96     std::string ConvertLiteralToString(std::vector<panda::pandasm::LiteralArray::Literal> &literalBuffer);
97     void CollectFuncDefineIns(panda::pandasm::Function *func);
98     void AddHeadAndTailInsForPatchFuncMain0(std::vector<panda::pandasm::Ins> &ins);
99     void AddTailInsForPatchFuncMain1(std::vector<panda::pandasm::Ins> &ins);
100     void CreateFunctionPatchMain0AndMain1(panda::pandasm::Function &patchFuncMain0,
101         panda::pandasm::Function &patchFuncMain1);
102     bool IsAnonymousOrSpecialOrDuplicateFunction(const std::string &funcName);
103     bool CompareLexenv(const std::string &funcName, const compiler::PandaGen *pg,
104         SymbolTable::OriginFunctionInfo &bytecodeInfo);
105     bool CompareClassHash(std::vector<std::pair<std::string, std::string>> &hashList,
106         SymbolTable::OriginFunctionInfo &bytecodeInfo);
107     void CollectClassMemberFunctions(const std::string &className, int64_t bufferIdx, LiteralBuffers &literalBuffers);
108     std::vector<std::string> GetLiteralMethods(int64_t bufferIdx, LiteralBuffers &literalBuffers);
109     void HandleModifiedClasses(panda::pandasm::Program *prog);
110     void HandleModifiedDefinedClassFunc(panda::pandasm::Program *prog);
111     int64_t GetLiteralIdxFromStringId(const std::string &stringId);
112 
113     std::mutex m_;
114     uint32_t topScopeIdx_ {0};
115     bool patchError_ {false};
116     bool generateSymbolFile_ {false};
117     bool generatePatch_ {false};
118     PatchFixKind patchFixKind_;
119     std::string recordName_;
120     std::string funcMain0_;
121     std::string patchMain0_;  // stores newly added function define ins, runtime will execute
122     std::string patchMain1_;  // stores modified function and class define ins, runtime will scan but not execute
123 
124     util::SymbolTable* symbolTable_ {nullptr};
125     ArenaAllocator allocator_;
126     ArenaUnorderedMap<std::string, util::SymbolTable::OriginFunctionInfo> *originFunctionInfo_ {nullptr};
127     ArenaUnorderedMap<std::string, std::string> *originModuleInfo_ {nullptr};
128     ArenaUnorderedMap<std::string, std::unordered_map<std::string, std::string>> *originRecordHashFunctionNames_ {
129         nullptr};
130     ArenaUnorderedMap<std::string, uint32_t> topScopeLexEnvs_;
131     ArenaSet<std::string> patchFuncNames_;
132     ArenaSet<std::string> newFuncNames_;
133     ArenaVector<panda::pandasm::Ins> funcDefineIns_;
134     ArenaSet<std::string> modifiedClassNames_;
135     ArenaUnorderedMap<std::string, std::vector<std::string>> classMemberFunctions_;
136     ArenaUnorderedMap<std::string, std::vector<std::string>> funcDefinedClasses_;
137 };
138 
139 } // namespace panda::es2panda::util
140 #endif // ES2PANDA_UTIL_PATCHFIX_H
141