1 /**
2 * Copyright (c) 2023-2024 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 return classLinker_->InitializeClass(coroutine, klass->GetRuntimeClass());
46 }
47
GetClassRoot(EtsClassRoot root) const48 EtsClass *EtsClassLinker::GetClassRoot(EtsClassRoot root) const
49 {
50 return EtsClass::FromRuntimeClass(ext_->GetClassRoot(static_cast<ark::ClassRoot>(root)));
51 }
52
GetClass(const char * name,bool needCopyDescriptor,ClassLinkerContext * classLinkerContext,ClassLinkerErrorHandler * errorHandler)53 EtsClass *EtsClassLinker::GetClass(const char *name, bool needCopyDescriptor, ClassLinkerContext *classLinkerContext,
54 ClassLinkerErrorHandler *errorHandler)
55 {
56 const uint8_t *classDescriptor = utf::CStringAsMutf8(name);
57 Class *cls = ext_->GetClass(classDescriptor, needCopyDescriptor, classLinkerContext, errorHandler);
58 return LIKELY(cls != nullptr) ? EtsClass::FromRuntimeClass(cls) : nullptr;
59 }
60
GetClass(const panda_file::File & pf,panda_file::File::EntityId id,ClassLinkerContext * classLinkerContext,ClassLinkerErrorHandler * errorHandler)61 EtsClass *EtsClassLinker::GetClass(const panda_file::File &pf, panda_file::File::EntityId id,
62 ClassLinkerContext *classLinkerContext, ClassLinkerErrorHandler *errorHandler)
63 {
64 Class *cls = ext_->GetClass(pf, id, classLinkerContext, errorHandler);
65 return LIKELY(cls != nullptr) ? EtsClass::FromRuntimeClass(cls) : nullptr;
66 }
67
GetMethod(const panda_file::File & pf,panda_file::File::EntityId id)68 Method *EtsClassLinker::GetMethod(const panda_file::File &pf, panda_file::File::EntityId id)
69 {
70 return classLinker_->GetMethod(pf, id);
71 }
72
GetAsyncImplMethod(Method * method,EtsCoroutine * coroutine)73 Method *EtsClassLinker::GetAsyncImplMethod(Method *method, EtsCoroutine *coroutine)
74 {
75 panda_file::File::EntityId asyncAnnId = EtsAnnotation::FindAsyncAnnotation(method);
76 ASSERT(asyncAnnId.IsValid());
77 const panda_file::File &pf = *method->GetPandaFile();
78 panda_file::AnnotationDataAccessor ada(pf, asyncAnnId);
79 auto implMethodId = ada.GetElement(0).GetScalarValue().Get<panda_file::File::EntityId>();
80 Method *result = GetMethod(pf, implMethodId);
81 if (result == nullptr) {
82 panda_file::MethodDataAccessor mda(pf, implMethodId);
83 PandaStringStream out;
84 out << "Cannot resolve async method " << mda.GetFullName();
85 ThrowEtsException(coroutine, panda_file_items::class_descriptors::NO_SUCH_METHOD_ERROR, out.str());
86 }
87 return result;
88 }
89
GetObjectClass()90 EtsClass *EtsClassLinker::GetObjectClass()
91 {
92 return EtsClass::FromRuntimeClass(ext_->GetObjectClass());
93 }
94
GetPromiseClass()95 EtsClass *EtsClassLinker::GetPromiseClass()
96 {
97 return EtsClass::FromRuntimeClass(ext_->GetPromiseClass());
98 }
99
GetPromiseRefClass()100 EtsClass *EtsClassLinker::GetPromiseRefClass()
101 {
102 return EtsClass::FromRuntimeClass(ext_->GetPromiseRefClass());
103 }
104
GetWaitersListClass()105 EtsClass *EtsClassLinker::GetWaitersListClass()
106 {
107 return EtsClass::FromRuntimeClass(ext_->GetWaitersListClass());
108 }
109
GetMutexClass()110 EtsClass *EtsClassLinker::GetMutexClass()
111 {
112 return EtsClass::FromRuntimeClass(ext_->GetMutexClass());
113 }
114
GetEventClass()115 EtsClass *EtsClassLinker::GetEventClass()
116 {
117 return EtsClass::FromRuntimeClass(ext_->GetEventClass());
118 }
119
GetCondVarClass()120 EtsClass *EtsClassLinker::GetCondVarClass()
121 {
122 return EtsClass::FromRuntimeClass(ext_->GetCondVarClass());
123 }
124
GetArrayClass()125 EtsClass *EtsClassLinker::GetArrayClass()
126 {
127 return EtsClass::FromRuntimeClass(ext_->GetArrayClass());
128 }
129
GetArrayBufferClass()130 EtsClass *EtsClassLinker::GetArrayBufferClass()
131 {
132 return EtsClass::FromRuntimeClass(ext_->GetArrayBufferClass());
133 }
134
GetStringBuilderClass()135 EtsClass *EtsClassLinker::GetStringBuilderClass()
136 {
137 return EtsClass::FromRuntimeClass(ext_->GetStringBuilderClass());
138 }
139
GetSharedMemoryClass()140 EtsClass *EtsClassLinker::GetSharedMemoryClass()
141 {
142 return EtsClass::FromRuntimeClass(ext_->GetSharedMemoryClass());
143 }
144
GetTypeAPIFieldClass()145 EtsClass *EtsClassLinker::GetTypeAPIFieldClass()
146 {
147 return EtsClass::FromRuntimeClass(ext_->GetTypeAPIFieldClass());
148 }
149
GetTypeAPIMethodClass()150 EtsClass *EtsClassLinker::GetTypeAPIMethodClass()
151 {
152 return EtsClass::FromRuntimeClass(ext_->GetTypeAPIMethodClass());
153 }
154
GetTypeAPIParameterClass()155 EtsClass *EtsClassLinker::GetTypeAPIParameterClass()
156 {
157 return EtsClass::FromRuntimeClass(ext_->GetTypeAPIParameterClass());
158 }
159
GetFunctionClass()160 EtsClass *EtsClassLinker::GetFunctionClass()
161 {
162 return EtsClass::FromRuntimeClass(ext_->GetFunctionClass());
163 }
164
GetFinalizableWeakRefClass()165 EtsClass *EtsClassLinker::GetFinalizableWeakRefClass()
166 {
167 return EtsClass::FromRuntimeClass(ext_->GetFinalizableWeakRefClass());
168 }
169
GetSubscribeOnAnotherPromiseMethod()170 Method *EtsClassLinker::GetSubscribeOnAnotherPromiseMethod()
171 {
172 return ext_->GetSubscribeOnAnotherPromiseMethod();
173 }
174
175 } // namespace ark::ets
176