• 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_HOTFIX_H
17 #define ES2PANDA_UTIL_HOTFIX_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/symbolTable.h>
25 
26 #include <mutex>
27 
28 namespace panda::es2panda::binder {
29 class VariableScope;
30 }  // namespace panda::es2panda::binder
31 
32 namespace panda::es2panda::compiler {
33 class PandaGen;
34 }  // namespace panda::es2panda::compiler
35 
36 namespace panda::es2panda::util {
37 class Hotfix {
38     using LiteralBuffers = ArenaVector<std::pair<int32_t, std::vector<panda::pandasm::LiteralArray::Literal>>>;
39 
40 public:
Hotfix(bool generateSymbolFile,bool generatePatch,bool hotReload,const std::string & recordName,util::SymbolTable * symbolTable)41     Hotfix(bool generateSymbolFile, bool generatePatch, bool hotReload, const std::string &recordName,
42         util::SymbolTable *symbolTable)
43         : generateSymbolFile_(generateSymbolFile), generatePatch_(generatePatch), hotReload_(hotReload),
44         recordName_(recordName),
45         symbolTable_(symbolTable),
46         allocator_(SpaceType::SPACE_TYPE_COMPILER, nullptr, true),
47         topScopeLexEnvs_(allocator_.Adapter()),
48         patchFuncNames_(allocator_.Adapter()),
49         newFuncNames_(allocator_.Adapter()),
50         funcDefineIns_(allocator_.Adapter()),
51         modifiedClassNames_(allocator_.Adapter()),
52         classMemberFunctions_(allocator_.Adapter()) {
53             originFunctionInfo_ = symbolTable_->GetOriginFunctionInfo();
54             originModuleInfo_ = symbolTable_->GetOriginModuleInfo();
55             patchMain0_ = recordName_ + ".patch_main_0";
56             patchMain1_ = recordName_ + ".patch_main_1";
57             funcMain0_ = recordName_ + ".func_main_0";
58         }
59 
60     void Finalize(panda::pandasm::Program **prog);
61     bool IsScopeValidToPatchLexical(binder::VariableScope *scope) const;
62     uint32_t GetSlotIdFromSymbolTable(const std::string &variableName);
63     void AllocSlotfromPatchEnv(const std::string &variableName);
64     uint32_t GetPatchLexicalIdx(const std::string &variableName);
65     bool IsPatchVar(uint32_t slot);
66     void ProcessFunction(const compiler::PandaGen *pg, panda::pandasm::Function *func, LiteralBuffers &literalBuffers);
67     void ProcessModule(const std::string &recordName, std::vector<panda::pandasm::LiteralArray::Literal> &moduleBuffer);
68     void ProcessJsonContentRecord(const std::string &recordName, const std::string &jsonFileContent);
69 
70 private:
71     void DumpFunctionInfo(const compiler::PandaGen *pg, panda::pandasm::Function *func, LiteralBuffers &literalBuffers);
72     void HandleFunction(const compiler::PandaGen *pg, panda::pandasm::Function *func, LiteralBuffers &literalBuffers);
73     std::vector<std::pair<std::string, size_t>> GenerateFunctionAndClassHash(panda::pandasm::Function *func,
74         LiteralBuffers &literalBuffers);
75     void DumpModuleInfo(const std::string &recordName, std::vector<panda::pandasm::LiteralArray::Literal> &moduleBuffer);
76     void ValidateModuleInfo(const std::string &recordName,
77         std::vector<panda::pandasm::LiteralArray::Literal> &moduleBuffer);
78     void DumpJsonContentRecInfo(const std::string &recordName, const std::string &jsonFileContent);
79     void ValidateJsonContentRecInfo(const std::string &recordName, const std::string &jsonFileContent);
80 
81     std::string ExpandLiteral(int64_t bufferIdx, LiteralBuffers &literalBuffers);
82     std::string ConvertLiteralToString(std::vector<panda::pandasm::LiteralArray::Literal> &literalBuffer);
83     void CollectFuncDefineIns(panda::pandasm::Function *func);
84     void AddHeadAndTailInsForPatchFuncMain0(std::vector<panda::pandasm::Ins> &ins);
85     void AddTailInsForPatchFuncMain1(std::vector<panda::pandasm::Ins> &ins);
86     void CreateFunctionPatchMain0AndMain1(panda::pandasm::Function &patchFuncMain0,
87         panda::pandasm::Function &patchFuncMain1);
88     bool IsAnonymousOrDuplicateNameFunction(const std::string &funcName);
89     bool CompareLexenv(const std::string &funcName, const compiler::PandaGen *pg,
90         SymbolTable::OriginFunctionInfo &bytecodeInfo);
91     bool CompareClassHash(std::vector<std::pair<std::string, size_t>> &hashList,
92         SymbolTable::OriginFunctionInfo &bytecodeInfo);
93     void CollectClassMemberFunctions(const std::string &className, int64_t bufferIdx, LiteralBuffers &literalBuffers);
94     std::vector<std::string> GetLiteralMethods(int64_t bufferIdx, LiteralBuffers &literalBuffers);
95     void HandleModifiedClasses(panda::pandasm::Program *prog);
96     int64_t GetLiteralIdxFromStringId(const std::string &stringId);
97 
98     std::mutex m_;
99     uint32_t topScopeIdx_ {0};
100     bool patchError_ {false};
101     bool generateSymbolFile_ {false};
102     bool generatePatch_ {false};
103     bool hotReload_ {false};
104     std::string recordName_;
105     std::string funcMain0_;
106     std::string patchMain0_;  // stores newly added function define ins, runtime will execute
107     std::string patchMain1_;  // stores modified function and class define ins, runtime will scan but not execute
108 
109     util::SymbolTable* symbolTable_ {nullptr};
110     ArenaAllocator allocator_;
111     ArenaUnorderedMap<std::string, util::SymbolTable::OriginFunctionInfo> *originFunctionInfo_ {nullptr};
112     ArenaUnorderedMap<std::string, std::string> *originModuleInfo_ {nullptr};
113     ArenaUnorderedMap<std::string, uint32_t> topScopeLexEnvs_;
114     ArenaSet<std::string> patchFuncNames_;
115     ArenaSet<std::string> newFuncNames_;
116     ArenaVector<panda::pandasm::Ins> funcDefineIns_;
117     ArenaSet<std::string> modifiedClassNames_;
118     ArenaUnorderedMap<std::string, std::vector<std::string>> classMemberFunctions_;
119 };
120 
121 } // namespace panda::es2panda::util
122 #endif // ES2PANDA_UTIL_HOTFIX_H
123