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_JSPANDAFILE_JS_PANDAFILE_MANAGER_H 17 #define ECMASCRIPT_JSPANDAFILE_JS_PANDAFILE_MANAGER_H 18 19 #include "ecmascript/jspandafile/js_pandafile.h" 20 #include "ecmascript/jspandafile/panda_file_translator.h" 21 #include "ecmascript/jspandafile/debug_info_extractor.h" 22 #include "ecmascript/platform/mutex.h" 23 24 namespace panda { 25 namespace ecmascript { 26 class Program; 27 28 class PUBLIC_API JSPandaFileManager { 29 public: 30 static JSPandaFileManager *GetInstance(); 31 32 ~JSPandaFileManager(); 33 34 JSHandle<Program> GenerateProgram(EcmaVM *vm, const JSPandaFile *jsPandaFile, std::string_view entryPoint); 35 36 template<ForHybridApp isHybrid = ForHybridApp::Normal> 37 std::shared_ptr<JSPandaFile> LoadJSPandaFile(JSThread *thread, const CString &filename, std::string_view entryPoint, 38 bool needUpdate = false, 39 const ExecuteTypes &executeType = ExecuteTypes::STATIC); 40 41 std::shared_ptr<JSPandaFile> LoadJSPandaFile(JSThread *thread, const CString &filename, std::string_view entryPoint, 42 const void *buffer, size_t size, bool needUpdate = false); 43 44 // load pandafile from secure mem 45 std::shared_ptr<JSPandaFile> LoadJSPandaFileSecure(JSThread *thread, const CString &filename, 46 std::string_view entryPoint, uint8_t *buffer, size_t size, 47 bool needUpdate = false, void *fileMapper = nullptr); 48 49 std::shared_ptr<JSPandaFile> LoadInsecureJSPandaFile(JSThread *thread, const CString &filename, 50 std::string_view entryPoint); 51 52 std::shared_ptr<JSPandaFile> OpenJSPandaFile(const CString &filename); 53 54 std::shared_ptr<JSPandaFile> OpenJSPandaFile(const CString &filename, const CString &desc); 55 56 std::shared_ptr<JSPandaFile> OpenJSPandaFileFromBuffer(uint8_t *buffer, size_t size, const CString &filename); 57 58 std::shared_ptr<JSPandaFile> NewJSPandaFile(const panda_file::File *pf, const CString &desc); 59 60 DebugInfoExtractor *GetJSPtExtractor(const JSPandaFile *jsPandaFile); 61 62 DebugInfoExtractor *GetJSPtExtractorAndExtract(const JSPandaFile *jsPandaFile); 63 64 DebugInfoExtractor *CpuProfilerGetJSPtExtractor(const JSPandaFile *jsPandaFile); 65 66 template<ForHybridApp isHybrid = ForHybridApp::Normal> 67 bool CheckFilePath(JSThread *thread, const CString &fileName); 68 69 // for debugger 70 template<typename Callback> EnumerateJSPandaFiles(Callback cb)71 void EnumerateJSPandaFiles(Callback cb) 72 { 73 LockHolder lock(jsPandaFileLock_); 74 for (const auto &item : loadedJSPandaFiles_) { 75 if (!cb(item.second)) { 76 return; 77 } 78 } 79 for (const auto &item : oldJSPandaFiles_) { 80 if (!cb(item)) { 81 return; 82 } 83 } 84 } 85 86 template<typename Callback> EnumerateNonVirtualJSPandaFiles(Callback cb)87 void EnumerateNonVirtualJSPandaFiles(Callback cb) 88 { 89 LockHolder lock(jsPandaFileLock_); 90 for (const auto &item : loadedJSPandaFiles_) { 91 if (!cb(item.second)) { 92 return; 93 } 94 } 95 for (const auto &item : oldJSPandaFiles_) { 96 if (!cb(item)) { 97 return; 98 } 99 } 100 } 101 std::shared_ptr<JSPandaFile> FindJSPandaFileByNormalizedName(const CString &normalizedName); 102 std::shared_ptr<JSPandaFile> FindJSPandaFileByMapBase(uintptr_t mapBase); 103 std::shared_ptr<JSPandaFile> FindJSPandaFile(const CString &filename); 104 void AddJSPandaFile(const std::shared_ptr<JSPandaFile> &jsPandaFile); 105 void RemoveJSPandaFile(const JSPandaFile *jsPandaFile); 106 void ClearNameMap(); 107 GetHapJSPandaFiles()108 std::unordered_set<std::shared_ptr<JSPandaFile>> GetHapJSPandaFiles() 109 { 110 std::unordered_set<std::shared_ptr<JSPandaFile>> hapJSPandaFiles; 111 LockHolder lock(jsPandaFileLock_); 112 for (const auto &item : loadedJSPandaFiles_) { 113 if (!item.second->IsBundlePack() && item.second->IsHapPath()) { 114 hapJSPandaFiles.emplace(item.second); 115 } 116 } 117 return hapJSPandaFiles; 118 } 119 120 private: 121 JSPandaFileManager() = default; 122 123 class JSPandaFileAllocator { 124 public: 125 static void *AllocateBuffer(size_t size); 126 static void FreeBuffer(void *mem); 127 }; 128 129 std::shared_ptr<JSPandaFile> GenerateJSPandaFile(JSThread *thread, const panda_file::File *pf, const CString &desc, 130 std::string_view entryPoint, void *fileMapper = nullptr); 131 std::shared_ptr<JSPandaFile> GetJSPandaFile(const panda_file::File *pf); 132 std::shared_ptr<JSPandaFile> FindJSPandaFileWithChecksum(const CString &filename, uint32_t checksum); 133 std::shared_ptr<JSPandaFile> FindJSPandaFileUnlocked(const CString &filename); 134 std::shared_ptr<JSPandaFile> GenerateJSPandafileFromBufferCache(JSThread *thread, 135 const CString &filename, 136 std::string_view entryPoint); 137 void ObsoleteLoadedJSPandaFile(const CString &filename); 138 139 static void *AllocateBuffer(size_t size, bool isBundlePack, CreateMode mode); 140 static void FreeBuffer(void *mem, size_t size, bool isBundlePack, CreateMode mode); 141 142 static bool UseSnapshot(JSThread *thread, JSPandaFile *jsPandaFile); 143 144 RecursiveMutex jsPandaFileLock_; 145 // JSPandaFile was shared by all vm. 146 std::unordered_map<const CString, std::shared_ptr<JSPandaFile>, CStringHash> loadedJSPandaFiles_; 147 // for plugin update. 148 std::set<std::shared_ptr<JSPandaFile>> oldJSPandaFiles_; 149 std::unordered_map<const JSPandaFile *, std::unique_ptr<DebugInfoExtractor>> extractors_; 150 151 friend class JSPandaFile; 152 }; 153 } // namespace ecmascript 154 } // namespace panda 155 #endif // ECMASCRIPT_JSPANDAFILE_JS_PANDAFILE_MANAGER_H 156