• 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 ECMASCRIPT_PATCH_PATCH_LOADER_H
17 #define ECMASCRIPT_PATCH_PATCH_LOADER_H
18 
19 #include "ecmascript/jspandafile/js_pandafile.h"
20 #include "ecmascript/js_tagged_value.h"
21 #include "ecmascript/js_thread.h"
22 #include "ecmascript/mem/c_containers.h"
23 #include "ecmascript/napi/include/jsnapi.h"
24 
25 namespace panda::ecmascript {
26 using PatchErrorCode = panda::JSNApi::PatchErrorCode;
27 using JSRecordInfo = JSPandaFile::JSRecordInfo;
28 
29 struct BaseMethodIndex {
30     uint32_t constpoolNum {UINT32_MAX};
31     uint32_t constpoolIndex {UINT32_MAX};
32     uint32_t literalIndex {UINT32_MAX};
33     bool operator < (const BaseMethodIndex &methodIndex) const
34     {
35         if (constpoolNum < methodIndex.constpoolNum) {
36             return true;
37         }
38         if (constpoolNum == methodIndex.constpoolNum && constpoolIndex < methodIndex.constpoolIndex) {
39             return true;
40         }
41         if (constpoolNum == methodIndex.constpoolNum && constpoolIndex == methodIndex.constpoolIndex) {
42             return literalIndex < methodIndex.literalIndex;
43         }
44         return false;
45     }
46 };
47 
48 struct PatchInfo {
49     // patch file name.
50     CString patchFileName;
51     // patch methodLiterals for load patch, <recordName, <methodName, MethodLiteral>>
52     CMap<CString, CMap<CString, MethodLiteral*>> patchMethodLiterals;
53     // base method info for unload patch, <BaseMethodIndex, base MethodLiteral>
54     CMap<BaseMethodIndex, MethodLiteral *> baseMethodInfo;
55     // save base constpool in global for avoid gc.
56     CVector<JSHandle<JSTaggedValue>> baseConstpools;
57 };
58 class PatchLoader {
59 public:
60     PatchLoader() = default;
61     ~PatchLoader() = default;
62     NO_COPY_SEMANTIC(PatchLoader);
63     NO_MOVE_SEMANTIC(PatchLoader);
64 
65     static PatchErrorCode LoadPatchInternal(JSThread *thread, const JSPandaFile *baseFile,
66                                             const JSPandaFile *patchFile, PatchInfo &patchInfo);
67     static PatchErrorCode UnloadPatchInternal(JSThread *thread, const CString &patchFileName,
68                                               const CString &baseFileName, PatchInfo &patchInfo);
69 
70     static MethodLiteral *FindSameMethod(PatchInfo &patchInfo, const JSPandaFile *baseFile, EntityId baseMethodId);
71 
72 private:
73     static PatchInfo GeneratePatchInfo(const JSPandaFile *patchFile);
74     static void FindAndReplaceSameMethod(JSThread *thread,
75                                          const JSPandaFile *baseFile,
76                                          const JSPandaFile *patchFile,
77                                          PatchInfo &patchInfo);
78     static void SaveBaseMethodInfo(PatchInfo &patchInfo, const JSPandaFile *baseFile,
79                                    EntityId baseMethodId, const BaseMethodIndex &indexs);
80     static void ReplaceMethod(JSThread *thread,
81                               Method *destMethod,
82                               MethodLiteral *srcMethodLiteral,
83                               JSTaggedValue srcConstpool);
84 
85     static bool ExecutePatchMain(JSThread *thread, const JSPandaFile *patchFile, const JSPandaFile *baseFile,
86                                  PatchInfo &patchInfo);
87 
88     static void ClearPatchInfo(JSThread *thread, const CString &patchFileName);
89 };
90 }  // namespace panda::ecmascript
91 #endif // ECMASCRIPT_PATCH_PATCH_LOADER_H
92