• 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     uint32_t GetEnvSizeOfFuncMain0();
70     void AllocSlotfromPatchEnv(const std::string &variableName);
71     uint32_t GetPatchLexicalIdx(const std::string &variableName);
72     bool IsAdditionalVarInPatch(uint32_t slot);
73     void ProcessFunction(const compiler::PandaGen *pg, panda::pandasm::Function *func, LiteralBuffers &literalBuffers);
74     void ProcessModule(const std::string &recordName, std::vector<panda::pandasm::LiteralArray::Literal> &moduleBuffer);
75     void ProcessJsonContentRecord(const std::string &recordName, const std::string &jsonFileContent);
76     void CheckAndRestoreSpecialFunctionName(uint32_t globalIndexForSpecialFunc, std::string &funcName,
77         std::string recordName);
78     bool IsDumpSymbolTable() const;
79     bool IsHotFix() const;
80     bool IsColdFix() const;
81     bool IsHotReload() const;
82 
83 private:
84     void DumpFunctionInfo(const compiler::PandaGen *pg, panda::pandasm::Function *func, LiteralBuffers &literalBuffers);
85     void HandleFunction(const compiler::PandaGen *pg, panda::pandasm::Function *func, LiteralBuffers &literalBuffers);
86     void CollectFunctionsWithDefinedClasses(std::string funcName, std::string className);
87     std::vector<std::pair<std::string, std::string>> GenerateFunctionAndClassHash(panda::pandasm::Function *func,
88         LiteralBuffers &literalBuffers);
89     void DumpModuleInfo(const std::string &recordName,
90         std::vector<panda::pandasm::LiteralArray::Literal> &moduleBuffer);
91     void ValidateModuleInfo(const std::string &recordName,
92         std::vector<panda::pandasm::LiteralArray::Literal> &moduleBuffer);
93     void DumpJsonContentRecInfo(const std::string &recordName, const std::string &jsonFileContent);
94     void ValidateJsonContentRecInfo(const std::string &recordName, const std::string &jsonFileContent);
95 
96     std::string ExpandLiteral(int64_t bufferIdx, LiteralBuffers &literalBuffers);
97     std::string ConvertLiteralToString(std::vector<panda::pandasm::LiteralArray::Literal> &literalBuffer);
98     void CollectFuncDefineIns(panda::pandasm::Function *func);
99     void AddHeadAndTailInsForPatchFuncMain0(std::vector<panda::pandasm::Ins> &ins);
100     void AddTailInsForPatchFuncMain1(std::vector<panda::pandasm::Ins> &ins);
101     void CreateFunctionPatchMain0AndMain1(panda::pandasm::Function &patchFuncMain0,
102         panda::pandasm::Function &patchFuncMain1);
103     bool IsAnonymousOrSpecialOrDuplicateFunction(const std::string &funcName);
104     bool CompareLexenv(const std::string &funcName, const compiler::PandaGen *pg,
105         SymbolTable::OriginFunctionInfo &bytecodeInfo);
106     bool CompareClassHash(std::vector<std::pair<std::string, std::string>> &hashList,
107         SymbolTable::OriginFunctionInfo &bytecodeInfo);
108     void CollectClassMemberFunctions(const std::string &className, int64_t bufferIdx, LiteralBuffers &literalBuffers);
109     std::vector<std::string> GetLiteralMethods(int64_t bufferIdx, LiteralBuffers &literalBuffers);
110     void HandleModifiedClasses(panda::pandasm::Program *prog);
111     void HandleModifiedDefinedClassFunc(panda::pandasm::Program *prog);
112     int64_t GetLiteralIdxFromStringId(const std::string &stringId);
113 
114     std::mutex m_;
115     uint32_t topScopeIdx_ {0};
116     bool patchError_ {false};
117     bool generateSymbolFile_ {false};
118     bool generatePatch_ {false};
119     PatchFixKind patchFixKind_;
120     std::string recordName_;
121     std::string funcMain0_;
122     std::string patchMain0_;  // stores newly added function define ins, runtime will execute
123     std::string patchMain1_;  // stores modified function and class define ins, runtime will scan but not execute
124 
125     util::SymbolTable* symbolTable_ {nullptr};
126     ArenaAllocator allocator_;
127     ArenaUnorderedMap<std::string, util::SymbolTable::OriginFunctionInfo> *originFunctionInfo_ {nullptr};
128     ArenaUnorderedMap<std::string, std::string> *originModuleInfo_ {nullptr};
129     ArenaUnorderedMap<std::string, std::unordered_map<std::string, std::string>> *originRecordHashFunctionNames_ {
130         nullptr};
131     ArenaUnorderedMap<std::string, uint32_t> topScopeLexEnvs_;
132     ArenaSet<std::string> patchFuncNames_;
133     ArenaSet<std::string> newFuncNames_;
134     ArenaVector<panda::pandasm::Ins> funcDefineIns_;
135     ArenaSet<std::string> modifiedClassNames_;
136     ArenaUnorderedMap<std::string, std::vector<std::string>> classMemberFunctions_;
137     ArenaUnorderedMap<std::string, std::vector<std::string>> funcDefinedClasses_;
138 };
139 
140 } // namespace panda::es2panda::util
141 #endif // ES2PANDA_UTIL_PATCHFIX_H
142