1 /** 2 * Copyright (c) 2025 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 PANDA_PLUGINS_ETS_RUNTIME_ETS_CLASS_LINKER_CONTEXT_H 17 #define PANDA_PLUGINS_ETS_RUNTIME_ETS_CLASS_LINKER_CONTEXT_H 18 19 #include <libpandafile/include/source_lang_enum.h> 20 21 #include "libpandabase/macros.h" 22 #include "os/mutex.h" 23 #include "plugins/ets/runtime/ets_class_linker_extension.h" 24 #include "plugins/ets/runtime/ets_vm.h" 25 #include "plugins/ets/runtime/types/ets_runtime_linker.h" 26 #include "runtime/class_linker_context.h" 27 #include "runtime/include/class_linker.h" 28 29 namespace ark::ets { 30 31 class EtsClassLinkerContext final : public ClassLinkerContext { 32 public: EtsClassLinkerContext(EtsRuntimeLinker * runtimeLinker)33 explicit EtsClassLinkerContext(EtsRuntimeLinker *runtimeLinker) : ClassLinkerContext(panda_file::SourceLang::ETS) 34 { 35 auto *objectStorage = PandaEtsVM::GetCurrent()->GetGlobalObjectStorage(); 36 // Store weak reference in order not to prevent collection of managed RuntimeLinker object. 37 auto *refToLinker = objectStorage->Add(runtimeLinker->GetCoreType(), mem::Reference::ObjectType::WEAK); 38 SetRefToLinker(refToLinker); 39 } 40 41 NO_COPY_SEMANTIC(EtsClassLinkerContext); 42 NO_MOVE_SEMANTIC(EtsClassLinkerContext); 43 ~EtsClassLinkerContext()44 ~EtsClassLinkerContext() override 45 { 46 EtsClassLinkerExtension::RemoveRefToLinker(this); 47 } 48 49 /// @brief Load class according to corresponding RuntimeLinker. 50 Class *LoadClass(const uint8_t *descriptor, bool needCopyDescriptor, 51 ClassLinkerErrorHandler *errorHandler) override; 52 53 void EnumeratePandaFiles(const std::function<bool(const panda_file::File &)> &cb) const override; 54 55 void EnumeratePandaFilesInChain(const std::function<bool(const panda_file::File &)> &cb) const override; 56 GetPandaFilePaths()57 PandaVector<std::string_view> GetPandaFilePaths() const override 58 { 59 PandaVector<std::string_view> filePaths; 60 EnumeratePandaFiles([&filePaths](const auto &pf) { 61 filePaths.emplace_back(pf.GetFilename()); 62 return true; 63 }); 64 return filePaths; 65 } 66 67 /// @brief Find and load class within panda files of this context. 68 Class *FindAndLoadClass(const uint8_t *descriptor, ClassLinkerErrorHandler *errorHandler); 69 GetRuntimeLinker()70 EtsRuntimeLinker *GetRuntimeLinker() const 71 { 72 auto *ref = GetRefToLinker(); 73 ASSERT(ref != nullptr); 74 auto *linker = PandaEtsVM::GetCurrent()->GetGlobalObjectStorage()->Get(ref); 75 ASSERT(linker != nullptr); 76 return EtsRuntimeLinker::FromCoreType(linker); 77 } 78 GetAbcFilesMutex()79 os::memory::RecursiveMutex &GetAbcFilesMutex() 80 { 81 return abcFilesMutex_; 82 } 83 84 private: 85 /** 86 * @brief Try to find and load class in AbcRuntimeLinker's chain without invoking managed implementations. 87 * 88 * @param descriptor of the searched class. 89 * @param errorHandler to be used during class loading, including CLASS_NOT_FOUND error. 90 * @param klass pointer for storing result, must contain nullptr. 91 * 92 * @returns true if linkers' chain was traversed successfully, false otherwise. 93 */ 94 bool TryLoadingClassFromNative(const uint8_t *descriptor, ClassLinkerErrorHandler *errorHandler, Class **klass); 95 96 void EnumeratePandaFilesImpl(const std::function<bool(const panda_file::File &)> &cb) const; 97 98 private: 99 os::memory::RecursiveMutex abcFilesMutex_; 100 }; 101 102 } // namespace ark::ets 103 104 #endif // !PANDA_PLUGINS_ETS_RUNTIME_ETS_CLASS_LINKER_CONTEXT_H 105