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