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