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 "dex/primitive.h"
22 #include "jni.h"
23 #include "obj_ptr.h"
24 
25 namespace art {
26 namespace mirror {
27 class Class;
28 class Object;
29 }  // namespace mirror
30 class ArtField;
31 class ArtMethod;
32 union JValue;
33 class ScopedObjectAccessAlreadyRunnable;
34 class ShadowFrame;
35 
36 ObjPtr<mirror::Object> BoxPrimitive(Primitive::Type src_class, const JValue& value)
37     REQUIRES_SHARED(Locks::mutator_lock_);
38 
39 bool UnboxPrimitiveForField(ObjPtr<mirror::Object> o,
40                             ObjPtr<mirror::Class> dst_class,
41                             ArtField* f,
42                             JValue* unboxed_value)
43     REQUIRES_SHARED(Locks::mutator_lock_);
44 
45 bool UnboxPrimitiveForResult(ObjPtr<mirror::Object> o,
46                              ObjPtr<mirror::Class> dst_class,
47                              JValue* unboxed_value)
48     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 jobject InvokeMethod(const ScopedObjectAccessAlreadyRunnable& soa,
101                      jobject method,
102                      jobject receiver,
103                      jobject args,
104                      size_t num_frames = 1)
105     REQUIRES_SHARED(Locks::mutator_lock_);
106 
107 // Special-casing of the above. Assumes that the method is the correct constructor, the class is
108 // initialized, and that the receiver is an instance of the class.
109 void InvokeConstructor(const ScopedObjectAccessAlreadyRunnable& soa,
110                        ArtMethod* constructor,
111                        ObjPtr<mirror::Object> receiver,
112                        jobject args)
113     REQUIRES_SHARED(Locks::mutator_lock_);
114 
115 ALWAYS_INLINE bool VerifyObjectIsClass(ObjPtr<mirror::Object> o, ObjPtr<mirror::Class> c)
116     REQUIRES_SHARED(Locks::mutator_lock_);
117 
118 bool VerifyAccess(Thread* self,
119                   ObjPtr<mirror::Object> obj,
120                   ObjPtr<mirror::Class> declaring_class,
121                   uint32_t access_flags,
122                   ObjPtr<mirror::Class>* calling_class,
123                   size_t num_frames)
124     REQUIRES_SHARED(Locks::mutator_lock_);
125 
126 // This version takes a known calling class.
127 bool VerifyAccess(ObjPtr<mirror::Object> obj,
128                   ObjPtr<mirror::Class> declaring_class,
129                   uint32_t access_flags,
130                   ObjPtr<mirror::Class> calling_class)
131     REQUIRES_SHARED(Locks::mutator_lock_);
132 
133 // Get the calling class by using a stack visitor, may return null for unattached native threads.
134 ObjPtr<mirror::Class> GetCallingClass(Thread* self, size_t num_frames)
135     REQUIRES_SHARED(Locks::mutator_lock_);
136 
137 void InvalidReceiverError(ObjPtr<mirror::Object> o, ObjPtr<mirror::Class> c)
138     REQUIRES_SHARED(Locks::mutator_lock_);
139 
140 void UpdateReference(Thread* self, jobject obj, ObjPtr<mirror::Object> result)
141     REQUIRES_SHARED(Locks::mutator_lock_);
142 
143 }  // namespace art
144 
145 #endif  // ART_RUNTIME_REFLECTION_H_
146