1 /** 2 * Copyright (c) 2021-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 #ifndef PANDA_RUNTIME_ETS_FFI_CLASSES_ETS_METHOD_H_ 17 #define PANDA_RUNTIME_ETS_FFI_CLASSES_ETS_METHOD_H_ 18 19 #include <string_view> 20 #include "libpandabase/macros.h" 21 #include "libpandabase/utils/utf.h" 22 #include "libpandafile/file_items.h" 23 #include "runtime/include/class_linker.h" 24 #include "runtime/include/method.h" 25 #include "runtime/include/thread.h" 26 #include "plugins/ets/runtime/ets_vm.h" 27 #include "plugins/ets/runtime/types/ets_class.h" 28 #include "plugins/ets/runtime/types/ets_type.h" 29 #include "plugins/ets/runtime/types/ets_string.h" 30 #include "plugins/ets/runtime/types/ets_value.h" 31 32 namespace ark { 33 class Value; 34 } // namespace ark 35 36 namespace ark::ets { 37 namespace napi { 38 class ScopedManagedCodeFix; 39 } // namespace napi 40 41 class PandaEtsEnv; 42 43 class EtsMethod { 44 public: 45 PANDA_PUBLIC_API static EtsMethod *FromTypeDescriptor(const PandaString &td); 46 47 PANDA_PUBLIC_API static bool IsMethod(const PandaString &td); 48 49 PANDA_PUBLIC_API EtsValue Invoke(napi::ScopedManagedCodeFix *s, Value *args); 50 InvokeVoid(napi::ScopedManagedCodeFix * s,Value * args)51 void InvokeVoid(napi::ScopedManagedCodeFix *s, Value *args) 52 { 53 Invoke(s, args); 54 } 55 GetParametersNum()56 uint32_t GetParametersNum() const 57 { 58 if (IsStatic()) { 59 return GetNumArgs(); 60 } 61 return GetNumArgs() - 1; 62 } 63 GetNumArgs()64 uint32_t GetNumArgs() const 65 { 66 return GetPandaMethod()->GetNumArgs(); 67 } 68 69 PANDA_PUBLIC_API uint32_t GetNumArgSlots() const; 70 GetArgType(size_t idx)71 EtsType GetArgType(size_t idx) const 72 { 73 EtsType etsType = ConvertPandaTypeToEtsType(GetPandaMethod()->GetArgType(idx)); 74 if (etsType == EtsType::VOID) { 75 LOG(FATAL, RUNTIME) << "VOID parameter"; 76 } 77 return etsType; 78 } 79 GetReturnValueType()80 EtsType GetReturnValueType() const 81 { 82 panda_file::Type pandaType = GetPandaMethod()->GetReturnType(); 83 return ConvertPandaTypeToEtsType(pandaType); 84 } 85 GetEffectiveArgType(size_t idx)86 EtsType GetEffectiveArgType(size_t idx) const 87 { 88 EtsType etsType = ConvertPandaTypeToEtsType(GetPandaMethod()->GetEffectiveArgType(idx)); 89 if (etsType == EtsType::VOID) { 90 LOG(FATAL, RUNTIME) << "VOID parameter"; 91 } 92 return etsType; 93 } 94 GetEffectiveReturnValueType()95 EtsType GetEffectiveReturnValueType() const 96 { 97 panda_file::Type pandaType = GetPandaMethod()->GetEffectiveReturnType(); 98 return ConvertPandaTypeToEtsType(pandaType); 99 } 100 GetRefArgType(size_t idx)101 const char *GetRefArgType(size_t idx) const 102 { 103 return utf::Mutf8AsCString(GetPandaMethod()->GetRefArgType(idx).data); 104 } 105 GetName()106 const char *GetName() const 107 { 108 return utf::Mutf8AsCString(GetPandaMethod()->GetName().data); 109 } 110 111 PandaString GetFullName(bool withSignature = false) const 112 { 113 return GetPandaMethod()->GetFullName(withSignature); 114 } 115 GetNameString()116 EtsString *GetNameString() 117 { 118 auto nameData = GetPandaMethod()->GetName(); 119 return EtsString::Resolve(nameData.data, nameData.utf16Length); 120 } 121 IsStatic()122 bool IsStatic() const 123 { 124 return GetPandaMethod()->IsStatic(); 125 } 126 IsSynthetic()127 bool IsSynthetic() const 128 { 129 return GetPandaMethod()->IsSynthetic(); 130 } 131 132 PANDA_PUBLIC_API bool IsEqualParametersType(EtsArray *params) const; 133 GetClass()134 EtsClass *GetClass() const 135 { 136 return EtsClass::FromRuntimeClass(GetPandaMethod()->GetClass()); 137 } 138 139 PANDA_PUBLIC_API EtsClass *ResolveArgType(uint32_t idx); 140 ResolveReturnType()141 EtsClass *ResolveReturnType() 142 { 143 Method::Proto proto = GetPandaMethod()->GetProto(); 144 const char *descriptor = proto.GetReturnTypeDescriptor().data(); 145 Runtime::GetCurrent()->GetClassLinker(); 146 return EtsClass::FromRuntimeClass(Runtime::GetCurrent()->GetClassLinker()->GetClass( 147 utf::CStringAsMutf8(descriptor), false, GetClass()->GetLoadContext())); 148 } 149 GetVTableID()150 size_t GetVTableID() const 151 { 152 return GetPandaMethod()->GetVTableIndex(); 153 } 154 IsPublic()155 bool IsPublic() const 156 { 157 return GetPandaMethod()->IsPublic(); 158 } 159 IsProtected()160 bool IsProtected() const 161 { 162 return GetPandaMethod()->IsProtected(); 163 } 164 IsPrivate()165 bool IsPrivate() const 166 { 167 return GetPandaMethod()->IsPrivate(); 168 } 169 IsNative()170 bool IsNative() const 171 { 172 return GetPandaMethod()->IsNative(); 173 } 174 IsFastNative()175 bool IsFastNative() const 176 { 177 return (GetAccessFlags() & ACC_FAST_NATIVE) != 0; 178 } 179 IsCriticalNative()180 bool IsCriticalNative() const 181 { 182 return (GetAccessFlags() & ACC_CRITICAL_NATIVE) != 0; 183 } 184 IsConstructor()185 bool IsConstructor() const 186 { 187 return GetPandaMethod()->IsConstructor(); 188 } 189 IsInstanceConstructor()190 bool IsInstanceConstructor() const 191 { 192 return GetPandaMethod()->IsInstanceConstructor(); 193 } 194 IsAbstract()195 bool IsAbstract() const 196 { 197 return GetPandaMethod()->IsAbstract(); 198 } 199 IsDeclaredIn(const EtsClass * klass)200 bool IsDeclaredIn(const EtsClass *klass) const 201 { 202 return GetClass() == klass; 203 } 204 IsGetter()205 bool IsGetter() 206 { 207 auto name = GetNameString(); 208 return name->GetMutf8().rfind(GETTER_BEGIN, 0) == 0; 209 } 210 IsSetter()211 bool IsSetter() 212 { 213 auto name = GetNameString(); 214 return name->GetMutf8().rfind(SETTER_BEGIN, 0) == 0; 215 } 216 RegisterNativeImpl(void * impl)217 void RegisterNativeImpl(void *impl) 218 { 219 ASSERT(IsNative()); 220 GetPandaMethod()->SetNativePointer(impl); 221 } 222 UnregisterNativeImpl()223 void UnregisterNativeImpl() 224 { 225 ASSERT(IsNative()); 226 GetPandaMethod()->SetNativePointer(nullptr); 227 } 228 GetAccessFlags()229 uint32_t GetAccessFlags() const 230 { 231 return GetPandaMethod()->GetAccessFlags(); 232 } 233 GetAccessLevel()234 AccessLevel GetAccessLevel() 235 { 236 if (GetPandaMethod()->IsPublic()) { 237 return AccessLevel::PUBLIC; 238 } 239 if (GetPandaMethod()->IsProtected()) { 240 return AccessLevel::PROTECTED; 241 } 242 if (GetPandaMethod()->IsPrivate()) { 243 return AccessLevel::PRIVATE; 244 } 245 return AccessLevel::DEFAULT; 246 } 247 GetMethodId()248 uint32_t GetMethodId() const 249 { 250 return GetPandaMethod()->GetFileId().GetOffset(); 251 } 252 253 PANDA_PUBLIC_API EtsMethod *GetOverriddenMethod(); 254 GetLineNumFromBytecodeOffset(uint32_t bcOffset)255 int32_t GetLineNumFromBytecodeOffset(uint32_t bcOffset) const 256 { 257 if (IsNative()) { 258 return -2; // -2 259 } 260 261 if (IsAbstract()) { 262 return -1; 263 } 264 265 return GetPandaMethod()->GetLineNumFromBytecodeOffset(bcOffset); 266 } 267 GetClassSourceFile()268 panda_file::File::StringData GetClassSourceFile() const 269 { 270 return GetPandaMethod()->GetClassSourceFile(); 271 } 272 FromRuntimeMethod(Method * method)273 static EtsMethod *FromRuntimeMethod(Method *method) 274 { 275 return reinterpret_cast<EtsMethod *>(method); 276 } 277 ToRuntimeMethod(EtsMethod * etsMethod)278 static Method *ToRuntimeMethod(EtsMethod *etsMethod) 279 { 280 return reinterpret_cast<Method *>(etsMethod); 281 } 282 283 EtsMethod() = delete; 284 ~EtsMethod() = delete; 285 GetPandaMethod()286 const Method *GetPandaMethod() const 287 { 288 return reinterpret_cast<const Method *>(this); 289 } 290 GetPandaMethod()291 Method *GetPandaMethod() 292 { 293 return reinterpret_cast<Method *>(this); 294 } 295 GetReturnTypeDescriptor()296 std::string_view GetReturnTypeDescriptor() 297 { 298 return GetPandaMethod()->GetProto().GetReturnTypeDescriptor(); 299 } 300 301 PANDA_PUBLIC_API PandaString GetMethodSignature(bool includeReturnType = true) const; 302 303 PANDA_PUBLIC_API PandaString GetDescriptor() const; 304 305 NO_COPY_SEMANTIC(EtsMethod); 306 NO_MOVE_SEMANTIC(EtsMethod); 307 }; 308 309 } // namespace ark::ets 310 311 #endif // PANDA_RUNTIME_ETS_FFI_CLASSES_ETS_METHOD_H_ 312