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