1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ART_RUNTIME_REFLECTION_H_
18 #define ART_RUNTIME_REFLECTION_H_
19 
20 #include "base/enums.h"
21 #include "base/locks.h"
22 #include "dex/primitive.h"
23 #include "jni.h"
24 #include "obj_ptr.h"
25 
26 namespace art {
27 namespace mirror {
28 class Class;
29 class Object;
30 }  // namespace mirror
31 class ArtField;
32 class ArtMethod;
33 union JValue;
34 class ScopedObjectAccessAlreadyRunnable;
35 class ShadowFrame;
36 
37 ObjPtr<mirror::Object> BoxPrimitive(Primitive::Type src_class, const JValue& value)
38     REQUIRES_SHARED(Locks::mutator_lock_);
39 
40 bool UnboxPrimitiveForField(ObjPtr<mirror::Object> o,
41                             ObjPtr<mirror::Class> dst_class,
42                             ArtField* f,
43                             JValue* unboxed_value)
44     REQUIRES_SHARED(Locks::mutator_lock_);
45 
46 bool UnboxPrimitiveForResult(ObjPtr<mirror::Object> o,
47                              ObjPtr<mirror::Class> dst_class,
48                              JValue* unboxed_value)
49     REQUIRES_SHARED(Locks::mutator_lock_);
50 
51 ALWAYS_INLINE bool ConvertPrimitiveValueNoThrow(Primitive::Type src_class,
52                                                 Primitive::Type dst_class,
53                                                 const JValue& src,
54                                                 JValue* dst)
55     REQUIRES_SHARED(Locks::mutator_lock_);
56 
57 ALWAYS_INLINE bool ConvertPrimitiveValue(bool unbox_for_result,
58                                          Primitive::Type src_class,
59                                          Primitive::Type dst_class,
60                                          const JValue& src,
61                                          JValue* dst)
62     REQUIRES_SHARED(Locks::mutator_lock_);
63 
64 // Invokes the given method (either an ArtMethod or a jmethodID) with direct/static semantics.
65 template<typename MethodType>
66 JValue InvokeWithVarArgs(const ScopedObjectAccessAlreadyRunnable& soa,
67                          jobject obj,
68                          MethodType mid,
69                          va_list args)
70     REQUIRES_SHARED(Locks::mutator_lock_);
71 
72 // Invokes the given method (either an ArtMethod or a jmethodID) with reflection semantics.
73 template<typename MethodType>
74 JValue InvokeWithJValues(const ScopedObjectAccessAlreadyRunnable& soa,
75                          jobject obj,
76                          MethodType mid,
77                          const jvalue* args)
78     REQUIRES_SHARED(Locks::mutator_lock_);
79 
80 // Invokes the given method (either an ArtMethod or a jmethodID) with virtual/interface semantics.
81 // Note this will perform lookup based on the 'obj' to determine which implementation of the given
82 // method should be invoked.
83 template<typename MethodType>
84 JValue InvokeVirtualOrInterfaceWithJValues(const ScopedObjectAccessAlreadyRunnable& soa,
85                                            jobject obj,
86                                            MethodType mid,
87                                            const jvalue* args)
88     REQUIRES_SHARED(Locks::mutator_lock_);
89 
90 // Invokes the given method (either an ArtMethod or a jmethodID) with virtual/interface semantics.
91 // Note this will perform lookup based on the 'obj' to determine which implementation of the given
92 // method should be invoked.
93 template<typename MethodType>
94 JValue InvokeVirtualOrInterfaceWithVarArgs(const ScopedObjectAccessAlreadyRunnable& soa,
95                                            jobject obj,
96                                            MethodType mid,
97                                            va_list args)
98     REQUIRES_SHARED(Locks::mutator_lock_);
99 
100 // num_frames is number of frames we look up for access check.
101 template<PointerSize pointer_size>
102 jobject InvokeMethod(const ScopedObjectAccessAlreadyRunnable& soa,
103                      jobject method,
104                      jobject receiver,
105                      jobject args,
106                      size_t num_frames = 1)
107     REQUIRES_SHARED(Locks::mutator_lock_);
108 
109 // Special-casing of the above. Assumes that the method is the correct constructor, the class is
110 // initialized, and that the receiver is an instance of the class.
111 void InvokeConstructor(const ScopedObjectAccessAlreadyRunnable& soa,
112                        ArtMethod* constructor,
113                        ObjPtr<mirror::Object> receiver,
114                        jobject args)
115     REQUIRES_SHARED(Locks::mutator_lock_);
116 
117 ALWAYS_INLINE bool VerifyObjectIsClass(ObjPtr<mirror::Object> o, ObjPtr<mirror::Class> c)
118     REQUIRES_SHARED(Locks::mutator_lock_);
119 
120 bool VerifyAccess(Thread* self,
121                   ObjPtr<mirror::Object> obj,
122                   ObjPtr<mirror::Class> declaring_class,
123                   uint32_t access_flags,
124                   ObjPtr<mirror::Class>* calling_class,
125                   size_t num_frames)
126     REQUIRES_SHARED(Locks::mutator_lock_);
127 
128 // This version takes a known calling class.
129 bool VerifyAccess(ObjPtr<mirror::Object> obj,
130                   ObjPtr<mirror::Class> declaring_class,
131                   uint32_t access_flags,
132                   ObjPtr<mirror::Class> calling_class)
133     REQUIRES_SHARED(Locks::mutator_lock_);
134 
135 // Get the calling class by using a stack visitor, may return null for unattached native threads.
136 ObjPtr<mirror::Class> GetCallingClass(Thread* self, size_t num_frames)
137     REQUIRES_SHARED(Locks::mutator_lock_);
138 
139 void InvalidReceiverError(ObjPtr<mirror::Object> o, ObjPtr<mirror::Class> c)
140     REQUIRES_SHARED(Locks::mutator_lock_);
141 
142 void UpdateReference(Thread* self, jobject obj, ObjPtr<mirror::Object> result)
143     REQUIRES_SHARED(Locks::mutator_lock_);
144 
145 }  // namespace art
146 
147 #endif  // ART_RUNTIME_REFLECTION_H_
148