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/locks.h"
21 #include "base/macros.h"
22 #include "base/pointer_size.h"
23 #include "dex/primitive.h"
24 #include "jni.h"
25 #include "obj_ptr.h"
26 
27 namespace art HIDDEN {
28 namespace mirror {
29 class Class;
30 class Object;
31 }  // namespace mirror
32 class ArtField;
33 class ArtMethod;
34 union JValue;
35 class ScopedObjectAccessAlreadyRunnable;
36 class ShadowFrame;
37 
38 EXPORT ObjPtr<mirror::Object> BoxPrimitive(Primitive::Type src_class, const JValue& value)
39     REQUIRES_SHARED(Locks::mutator_lock_);
40 
41 EXPORT bool UnboxPrimitiveForField(ObjPtr<mirror::Object> o,
42                                    ObjPtr<mirror::Class> dst_class,
43                                    ArtField* f,
44                                    JValue* unboxed_value) REQUIRES_SHARED(Locks::mutator_lock_);
45 
46 EXPORT bool UnboxPrimitiveForResult(ObjPtr<mirror::Object> o,
47                                     ObjPtr<mirror::Class> dst_class,
48                                     JValue* unboxed_value) REQUIRES_SHARED(Locks::mutator_lock_);
49 
50 ALWAYS_INLINE bool ConvertPrimitiveValueNoThrow(Primitive::Type src_class,
51                                                 Primitive::Type dst_class,
52                                                 const JValue& src,
53                                                 JValue* dst)
54     REQUIRES_SHARED(Locks::mutator_lock_);
55 
56 ALWAYS_INLINE bool ConvertPrimitiveValue(bool unbox_for_result,
57                                          Primitive::Type src_class,
58                                          Primitive::Type dst_class,
59                                          const JValue& src,
60                                          JValue* dst)
61     REQUIRES_SHARED(Locks::mutator_lock_);
62 
63 // Invokes the given method (either an ArtMethod or a jmethodID) with direct/static semantics.
64 template<typename MethodType>
65 JValue InvokeWithVarArgs(const ScopedObjectAccessAlreadyRunnable& soa,
66                          jobject obj,
67                          MethodType mid,
68                          va_list args)
69     REQUIRES_SHARED(Locks::mutator_lock_);
70 
71 // Invokes the given method (either an ArtMethod or a jmethodID) with reflection semantics.
72 template<typename MethodType>
73 JValue InvokeWithJValues(const ScopedObjectAccessAlreadyRunnable& soa,
74                          jobject obj,
75                          MethodType mid,
76                          const jvalue* args)
77     REQUIRES_SHARED(Locks::mutator_lock_);
78 
79 // Invokes the given method (either an ArtMethod or a jmethodID) with virtual/interface semantics.
80 // Note this will perform lookup based on the 'obj' to determine which implementation of the given
81 // method should be invoked.
82 template<typename MethodType>
83 JValue InvokeVirtualOrInterfaceWithJValues(const ScopedObjectAccessAlreadyRunnable& soa,
84                                            jobject obj,
85                                            MethodType mid,
86                                            const jvalue* args)
87     REQUIRES_SHARED(Locks::mutator_lock_);
88 
89 // Invokes the given method (either an ArtMethod or a jmethodID) with virtual/interface semantics.
90 // Note this will perform lookup based on the 'obj' to determine which implementation of the given
91 // method should be invoked.
92 template<typename MethodType>
93 JValue InvokeVirtualOrInterfaceWithVarArgs(const ScopedObjectAccessAlreadyRunnable& soa,
94                                            jobject obj,
95                                            MethodType mid,
96                                            va_list args)
97     REQUIRES_SHARED(Locks::mutator_lock_);
98 
99 // num_frames is number of frames we look up for access check.
100 template<PointerSize pointer_size>
101 NO_STACK_PROTECTOR
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