• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2023-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 #include "plugins/ets/runtime/ets_annotation.h"
17 #include "plugins/ets/runtime/ets_class_linker.h"
18 #include "plugins/ets/runtime/ets_class_linker_extension.h"
19 #include "plugins/ets/runtime/ets_coroutine.h"
20 #include "plugins/ets/runtime/ets_exceptions.h"
21 #include "plugins/ets/runtime/ets_panda_file_items.h"
22 #include "plugins/ets/runtime/types/ets_class.h"
23 #include "types/ets_field.h"
24 
25 namespace ark::ets {
26 
EtsClassLinker(ClassLinker * classLinker)27 EtsClassLinker::EtsClassLinker(ClassLinker *classLinker) : classLinker_(classLinker) {}
28 
29 /*static*/
Create(ClassLinker * classLinker)30 Expected<PandaUniquePtr<EtsClassLinker>, PandaString> EtsClassLinker::Create(ClassLinker *classLinker)
31 {
32     PandaUniquePtr<EtsClassLinker> etsClassLinker = MakePandaUnique<EtsClassLinker>(classLinker);
33     return Expected<PandaUniquePtr<EtsClassLinker>, PandaString>(std::move(etsClassLinker));
34 }
35 
Initialize()36 bool EtsClassLinker::Initialize()
37 {
38     ClassLinkerExtension *ext = classLinker_->GetExtension(panda_file::SourceLang::ETS);
39     ext_ = EtsClassLinkerExtension::FromCoreType(ext);
40     return true;
41 }
42 
InitializeClass(EtsCoroutine * coroutine,EtsClass * klass)43 bool EtsClassLinker::InitializeClass(EtsCoroutine *coroutine, EtsClass *klass)
44 {
45     ASSERT(klass != nullptr);
46     return classLinker_->InitializeClass(coroutine, klass->GetRuntimeClass());
47 }
48 
GetClassRoot(EtsClassRoot root) const49 EtsClass *EtsClassLinker::GetClassRoot(EtsClassRoot root) const
50 {
51     return EtsClass::FromRuntimeClass(ext_->GetClassRoot(static_cast<ark::ClassRoot>(root)));
52 }
53 
GetClass(const char * name,bool needCopyDescriptor,ClassLinkerContext * classLinkerContext,ClassLinkerErrorHandler * errorHandler)54 EtsClass *EtsClassLinker::GetClass(const char *name, bool needCopyDescriptor, ClassLinkerContext *classLinkerContext,
55                                    ClassLinkerErrorHandler *errorHandler)
56 {
57     const uint8_t *classDescriptor = utf::CStringAsMutf8(name);
58     Class *cls = ext_->GetClass(classDescriptor, needCopyDescriptor, classLinkerContext, errorHandler);
59     return LIKELY(cls != nullptr) ? EtsClass::FromRuntimeClass(cls) : nullptr;
60 }
61 
GetClass(const panda_file::File & pf,panda_file::File::EntityId id,ClassLinkerContext * classLinkerContext,ClassLinkerErrorHandler * errorHandler)62 EtsClass *EtsClassLinker::GetClass(const panda_file::File &pf, panda_file::File::EntityId id,
63                                    ClassLinkerContext *classLinkerContext, ClassLinkerErrorHandler *errorHandler)
64 {
65     Class *cls = ext_->GetClass(pf, id, classLinkerContext, errorHandler);
66     return LIKELY(cls != nullptr) ? EtsClass::FromRuntimeClass(cls) : nullptr;
67 }
68 
GetMethod(const panda_file::File & pf,panda_file::File::EntityId id,ClassLinkerContext * classLinkerContext,ClassLinkerErrorHandler * errorHandler)69 Method *EtsClassLinker::GetMethod(const panda_file::File &pf, panda_file::File::EntityId id,
70                                   ClassLinkerContext *classLinkerContext, ClassLinkerErrorHandler *errorHandler)
71 {
72     return classLinker_->GetMethod(pf, id, classLinkerContext, errorHandler);
73 }
74 
GetAsyncImplMethod(Method * method,EtsCoroutine * coroutine)75 Method *EtsClassLinker::GetAsyncImplMethod(Method *method, EtsCoroutine *coroutine)
76 {
77     ASSERT(method != nullptr);
78     panda_file::File::EntityId asyncAnnId = EtsAnnotation::FindAsyncAnnotation(method);
79     ASSERT(asyncAnnId.IsValid());
80     const panda_file::File &pf = *method->GetPandaFile();
81     panda_file::AnnotationDataAccessor ada(pf, asyncAnnId);
82     auto implMethodId = ada.GetElement(0).GetScalarValue().Get<panda_file::File::EntityId>();
83     auto *ctx = method->GetClass()->GetLoadContext();
84     Method *result = GetMethod(pf, implMethodId, ctx);
85     if (result == nullptr) {
86         panda_file::MethodDataAccessor mda(pf, implMethodId);
87         PandaStringStream out;
88         out << "Cannot resolve async method " << mda.GetFullName();
89         ThrowEtsException(coroutine, panda_file_items::class_descriptors::LINKER_UNRESOLVED_METHOD_ERROR, out.str());
90     }
91     return result;
92 }
93 
94 }  // namespace ark::ets
95