1 /* 2 * Copyright (c) 2021 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_INTERPRETER_RUNTIME_INTERFACE_H_ 17 #define PANDA_RUNTIME_INTERPRETER_RUNTIME_INTERFACE_H_ 18 19 #include <memory> 20 21 #include "libpandabase/utils/logger.h" 22 #include "libpandafile/file_items.h" 23 #include "runtime/entrypoints/entrypoints.h" 24 #include "runtime/include/class_linker-inl.h" 25 #include "runtime/include/coretypes/array.h" 26 #include "runtime/include/coretypes/string.h" 27 #include "runtime/include/exceptions.h" 28 #include "runtime/include/field.h" 29 #include "runtime/include/managed_thread.h" 30 #include "runtime/include/method.h" 31 #include "runtime/include/runtime.h" 32 #include "runtime/mem/gc/gc.h" 33 #include "runtime/tooling/pt_thread_info.h" 34 35 namespace panda::interpreter { 36 37 class RuntimeInterface { 38 public: 39 static constexpr bool NEED_READ_BARRIER = true; 40 static constexpr bool NEED_WRITE_BARRIER = true; 41 ResolveString(PandaVM * vm,const Method & caller,BytecodeId id)42 static coretypes::String *ResolveString(PandaVM *vm, const Method &caller, BytecodeId id) 43 { 44 return Runtime::GetCurrent()->ResolveString(vm, caller, id.AsFileId()); 45 } 46 ResolveMethod(ManagedThread * thread,const Method & caller,BytecodeId id)47 static Method *ResolveMethod(ManagedThread *thread, const Method &caller, BytecodeId id) 48 { 49 auto resolved_id = caller.GetClass()->ResolveMethodIndex(id.AsIndex()); 50 auto *class_linker = Runtime::GetCurrent()->GetClassLinker(); 51 auto *method = class_linker->GetMethod(caller, resolved_id); 52 if (method == nullptr) { 53 return nullptr; 54 } 55 56 auto *klass = method->GetClass(); 57 if (!klass->IsInitialized() && !class_linker->InitializeClass(thread, klass)) { 58 return nullptr; 59 } 60 61 return method; 62 } 63 GetMethodName(const Method * caller,BytecodeId method_id)64 static const uint8_t *GetMethodName(const Method *caller, BytecodeId method_id) 65 { 66 auto resolved_id = caller->GetClass()->ResolveMethodIndex(method_id.AsIndex()); 67 const auto *pf = caller->GetPandaFile(); 68 const panda_file::MethodDataAccessor MDA(*pf, resolved_id); 69 return pf->GetStringData(MDA.GetNameId()).data; 70 } 71 GetMethodClass(const Method * caller,BytecodeId method_id)72 static Class *GetMethodClass(const Method *caller, BytecodeId method_id) 73 { 74 auto resolved_id = caller->GetClass()->ResolveMethodIndex(method_id.AsIndex()); 75 const auto *pf = caller->GetPandaFile(); 76 const panda_file::MethodDataAccessor MDA(*pf, resolved_id); 77 auto class_id = MDA.GetClassId(); 78 79 auto *class_linker = Runtime::GetCurrent()->GetClassLinker(); 80 return class_linker->GetClass(*caller, class_id); 81 } 82 GetMethodArgumentsCount(Method * caller,BytecodeId method_id)83 static uint32_t GetMethodArgumentsCount(Method *caller, BytecodeId method_id) 84 { 85 auto resolved_id = caller->GetClass()->ResolveMethodIndex(method_id.AsIndex()); 86 auto *pf = caller->GetPandaFile(); 87 panda_file::MethodDataAccessor mda(*pf, resolved_id); 88 panda_file::ProtoDataAccessor pda(*pf, mda.GetProtoId()); 89 return pda.GetNumArgs(); 90 } 91 ResolveField(ManagedThread * thread,const Method & caller,BytecodeId id)92 static Field *ResolveField(ManagedThread *thread, const Method &caller, BytecodeId id) 93 { 94 auto resolved_id = caller.GetClass()->ResolveFieldIndex(id.AsIndex()); 95 auto *class_linker = Runtime::GetCurrent()->GetClassLinker(); 96 auto *field = class_linker->GetField(caller, resolved_id); 97 if (field == nullptr) { 98 return nullptr; 99 } 100 101 auto *klass = field->GetClass(); 102 if (!klass->IsInitialized() && !class_linker->InitializeClass(thread, field->GetClass())) { 103 return nullptr; 104 } 105 106 return field; 107 } 108 109 template <bool need_init> ResolveClass(ManagedThread * thread,const Method & caller,BytecodeId id)110 static Class *ResolveClass(ManagedThread *thread, const Method &caller, BytecodeId id) 111 { 112 auto resolved_id = caller.GetClass()->ResolveClassIndex(id.AsIndex()); 113 ClassLinker *class_linker = Runtime::GetCurrent()->GetClassLinker(); 114 Class *klass = class_linker->GetClass(caller, resolved_id); 115 116 if (klass == nullptr) { 117 return nullptr; 118 } 119 120 if (need_init) { 121 auto *klass_linker = Runtime::GetCurrent()->GetClassLinker(); 122 if (!klass->IsInitialized() && !klass_linker->InitializeClass(thread, klass)) { 123 return nullptr; 124 } 125 } 126 127 return klass; 128 } 129 ResolveLiteralArray(PandaVM * vm,const Method & caller,BytecodeId id)130 static coretypes::Array *ResolveLiteralArray(PandaVM *vm, const Method &caller, BytecodeId id) 131 { 132 return Runtime::GetCurrent()->ResolveLiteralArray(vm, caller, id.AsFileId()); 133 } 134 GetCompilerHotnessThreshold()135 static uint32_t GetCompilerHotnessThreshold() 136 { 137 return 0; 138 } 139 IsCompilerEnableJit()140 static bool IsCompilerEnableJit() 141 { 142 return false; 143 } 144 SetCurrentFrame(ManagedThread * thread,Frame * frame)145 static void SetCurrentFrame(ManagedThread *thread, Frame *frame) 146 { 147 thread->SetCurrentFrame(frame); 148 } 149 GetNotificationManager()150 static RuntimeNotificationManager *GetNotificationManager() 151 { 152 return Runtime::GetCurrent()->GetNotificationManager(); 153 } 154 CreateArray(Class * klass,coretypes::array_size_t length)155 static coretypes::Array *CreateArray(Class *klass, coretypes::array_size_t length) 156 { 157 return coretypes::Array::Create(klass, length); 158 } 159 160 static ObjectHeader *CreateObject(Class *klass); 161 InvokeMethod(ManagedThread * thread,Method * method,Value * args)162 static Value InvokeMethod(ManagedThread *thread, Method *method, Value *args) 163 { 164 return method->Invoke(thread, args); 165 } 166 FindCatchBlock(const Method & method,ObjectHeader * exception,uint32_t pc)167 static uint32_t FindCatchBlock(const Method &method, ObjectHeader *exception, uint32_t pc) 168 { 169 return method.FindCatchBlock(exception->ClassAddr<Class>(), pc); 170 } 171 ThrowNullPointerException()172 static void ThrowNullPointerException() 173 { 174 return panda::ThrowNullPointerException(); 175 } 176 ThrowArrayIndexOutOfBoundsException(coretypes::array_ssize_t idx,coretypes::array_size_t length)177 static void ThrowArrayIndexOutOfBoundsException(coretypes::array_ssize_t idx, coretypes::array_size_t length) 178 { 179 panda::ThrowArrayIndexOutOfBoundsException(idx, length); 180 } 181 ThrowNegativeArraySizeException(coretypes::array_ssize_t size)182 static void ThrowNegativeArraySizeException(coretypes::array_ssize_t size) 183 { 184 panda::ThrowNegativeArraySizeException(size); 185 } 186 ThrowArithmeticException()187 static void ThrowArithmeticException() 188 { 189 panda::ThrowArithmeticException(); 190 } 191 ThrowClassCastException(Class * dst_type,Class * src_type)192 static void ThrowClassCastException(Class *dst_type, Class *src_type) 193 { 194 panda::ThrowClassCastException(dst_type, src_type); 195 } 196 ThrowAbstractMethodError(Method * method)197 static void ThrowAbstractMethodError(Method *method) 198 { 199 panda::ThrowAbstractMethodError(method); 200 } 201 ThrowOutOfMemoryError(const PandaString & msg)202 static void ThrowOutOfMemoryError(const PandaString &msg) 203 { 204 panda::ThrowOutOfMemoryError(msg); 205 } 206 ThrowArrayStoreException(Class * array_class,Class * elem_class)207 static void ThrowArrayStoreException(Class *array_class, Class *elem_class) 208 { 209 panda::ThrowArrayStoreException(array_class, elem_class); 210 } 211 ThrowIllegalAccessException(const PandaString & msg)212 static void ThrowIllegalAccessException(const PandaString &msg) 213 { 214 panda::ThrowIllegalAccessException(msg); 215 } 216 ThrowVerificationException(const PandaString & msg)217 static void ThrowVerificationException(const PandaString &msg) 218 { 219 panda::ThrowVerificationException(msg); 220 } 221 ThrowTypedErrorDyn(const std::string & msg)222 static void ThrowTypedErrorDyn(const std::string &msg) 223 { 224 panda::ThrowTypedErrorDyn(msg); 225 } 226 ThrowReferenceErrorDyn(const std::string & msg)227 static void ThrowReferenceErrorDyn(const std::string &msg) 228 { 229 panda::ThrowReferenceErrorDyn(msg); 230 } 231 CreateFrame(size_t nregs,Method * method,Frame * prev)232 static Frame *CreateFrame(size_t nregs, Method *method, Frame *prev) 233 { 234 return panda::CreateFrame(nregs, method, prev); 235 } 236 CreateFrameWithActualArgs(uint32_t nregs,uint32_t num_actual_args,Method * method,Frame * prev)237 static Frame *CreateFrameWithActualArgs(uint32_t nregs, uint32_t num_actual_args, Method *method, Frame *prev) 238 { 239 return panda::CreateFrameWithActualArgs(nregs, num_actual_args, method, prev); 240 } 241 CreateFrameWithActualArgs(uint32_t size,uint32_t nregs,uint32_t num_actual_args,Method * method,Frame * prev)242 static Frame *CreateFrameWithActualArgs(uint32_t size, uint32_t nregs, uint32_t num_actual_args, Method *method, 243 Frame *prev) 244 { 245 return panda::CreateFrameWithActualArgsAndSize(size, nregs, num_actual_args, method, prev); 246 } 247 FreeFrame(Frame * frame)248 static void FreeFrame(Frame *frame) 249 { 250 panda::FreeFrame(frame); 251 } 252 ThreadSuspension(MTManagedThread * thread)253 static void ThreadSuspension(MTManagedThread *thread) 254 { 255 thread->WaitSuspension(); 256 } 257 ThreadRuntimeTermination(MTManagedThread * thread)258 static void ThreadRuntimeTermination(MTManagedThread *thread) 259 { 260 thread->TerminationLoop(); 261 } 262 GetLanguageContext(Method * method_ptr)263 static panda_file::SourceLang GetLanguageContext(Method *method_ptr) 264 { 265 LanguageContext ctx = Runtime::GetCurrent()->GetLanguageContext(*method_ptr); 266 return ctx.GetLanguage(); 267 } 268 269 /** 270 * \brief Executes external implementation of safepoint 271 * 272 * It is not-inlined version of safepoint. 273 * Shouldn't be used in production in the JIT. 274 */ Safepoint()275 static void Safepoint() 276 { 277 MTManagedThread *thread = MTManagedThread::GetCurrent(); 278 if (UNLIKELY(thread->IsRuntimeTerminated())) { 279 ThreadRuntimeTermination(thread); 280 } 281 if (thread->IsSuspended()) { 282 ThreadSuspension(thread); 283 } 284 } 285 GetLanguageContext(const Method & method)286 static LanguageContext GetLanguageContext(const Method &method) 287 { 288 return Runtime::GetCurrent()->GetLanguageContext(method); 289 } 290 }; 291 292 } // namespace panda::interpreter 293 294 #endif // PANDA_RUNTIME_INTERPRETER_RUNTIME_INTERFACE_H_ 295