• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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