• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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 #include "java_lang_Class.h"
18 
19 #include <iostream>
20 
21 #include "art_field-inl.h"
22 #include "art_method-inl.h"
23 #include "base/enums.h"
24 #include "class_linker-inl.h"
25 #include "common_throws.h"
26 #include "dex_file-inl.h"
27 #include "dex_file_annotations.h"
28 #include "jni_internal.h"
29 #include "mirror/class-inl.h"
30 #include "mirror/class_loader.h"
31 #include "mirror/field-inl.h"
32 #include "mirror/method.h"
33 #include "mirror/object-inl.h"
34 #include "mirror/object_array-inl.h"
35 #include "mirror/string-inl.h"
36 #include "native_util.h"
37 #include "nativehelper/jni_macros.h"
38 #include "nativehelper/ScopedLocalRef.h"
39 #include "nativehelper/ScopedUtfChars.h"
40 #include "nth_caller_visitor.h"
41 #include "obj_ptr-inl.h"
42 #include "reflection.h"
43 #include "scoped_fast_native_object_access-inl.h"
44 #include "scoped_thread_state_change-inl.h"
45 #include "utf.h"
46 #include "well_known_classes.h"
47 
48 namespace art {
49 
DecodeClass(const ScopedFastNativeObjectAccess & soa,jobject java_class)50 ALWAYS_INLINE static inline ObjPtr<mirror::Class> DecodeClass(
51     const ScopedFastNativeObjectAccess& soa, jobject java_class)
52     REQUIRES_SHARED(Locks::mutator_lock_) {
53   ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class);
54   DCHECK(c != nullptr);
55   DCHECK(c->IsClass());
56   // TODO: we could EnsureInitialized here, rather than on every reflective get/set or invoke .
57   // For now, we conservatively preserve the old dalvik behavior. A quick "IsInitialized" check
58   // every time probably doesn't make much difference to reflection performance anyway.
59   return c;
60 }
61 
62 // "name" is in "binary name" format, e.g. "dalvik.system.Debug$1".
Class_classForName(JNIEnv * env,jclass,jstring javaName,jboolean initialize,jobject javaLoader)63 static jclass Class_classForName(JNIEnv* env, jclass, jstring javaName, jboolean initialize,
64                                  jobject javaLoader) {
65   ScopedFastNativeObjectAccess soa(env);
66   ScopedUtfChars name(env, javaName);
67   if (name.c_str() == nullptr) {
68     return nullptr;
69   }
70 
71   // We need to validate and convert the name (from x.y.z to x/y/z).  This
72   // is especially handy for array types, since we want to avoid
73   // auto-generating bogus array classes.
74   if (!IsValidBinaryClassName(name.c_str())) {
75     soa.Self()->ThrowNewExceptionF("Ljava/lang/ClassNotFoundException;",
76                                    "Invalid name: %s", name.c_str());
77     return nullptr;
78   }
79 
80   std::string descriptor(DotToDescriptor(name.c_str()));
81   StackHandleScope<2> hs(soa.Self());
82   Handle<mirror::ClassLoader> class_loader(
83       hs.NewHandle(soa.Decode<mirror::ClassLoader>(javaLoader)));
84   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
85   Handle<mirror::Class> c(
86       hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader)));
87   if (c == nullptr) {
88     ScopedLocalRef<jthrowable> cause(env, env->ExceptionOccurred());
89     env->ExceptionClear();
90     jthrowable cnfe = reinterpret_cast<jthrowable>(
91         env->NewObject(WellKnownClasses::java_lang_ClassNotFoundException,
92                        WellKnownClasses::java_lang_ClassNotFoundException_init,
93                        javaName,
94                        cause.get()));
95     if (cnfe != nullptr) {
96       // Make sure allocation didn't fail with an OOME.
97       env->Throw(cnfe);
98     }
99     return nullptr;
100   }
101   if (initialize) {
102     class_linker->EnsureInitialized(soa.Self(), c, true, true);
103   }
104   return soa.AddLocalReference<jclass>(c.Get());
105 }
106 
Class_getNameNative(JNIEnv * env,jobject javaThis)107 static jstring Class_getNameNative(JNIEnv* env, jobject javaThis) {
108   ScopedFastNativeObjectAccess soa(env);
109   StackHandleScope<1> hs(soa.Self());
110   ObjPtr<mirror::Class> c = DecodeClass(soa, javaThis);
111   return soa.AddLocalReference<jstring>(mirror::Class::ComputeName(hs.NewHandle(c)));
112 }
113 
114 // TODO: Move this to mirror::Class ? Other mirror types that commonly appear
115 // as arrays have a GetArrayClass() method.
GetClassArrayClass(Thread * self)116 static ObjPtr<mirror::Class> GetClassArrayClass(Thread* self)
117     REQUIRES_SHARED(Locks::mutator_lock_) {
118   ObjPtr<mirror::Class> class_class = mirror::Class::GetJavaLangClass();
119   return Runtime::Current()->GetClassLinker()->FindArrayClass(self, &class_class);
120 }
121 
Class_getInterfacesInternal(JNIEnv * env,jobject javaThis)122 static jobjectArray Class_getInterfacesInternal(JNIEnv* env, jobject javaThis) {
123   ScopedFastNativeObjectAccess soa(env);
124   StackHandleScope<4> hs(soa.Self());
125   Handle<mirror::Class> klass = hs.NewHandle(DecodeClass(soa, javaThis));
126 
127   if (klass->IsProxyClass()) {
128     return soa.AddLocalReference<jobjectArray>(klass->GetProxyInterfaces()->Clone(soa.Self()));
129   }
130 
131   const DexFile::TypeList* iface_list = klass->GetInterfaceTypeList();
132   if (iface_list == nullptr) {
133     return nullptr;
134   }
135 
136   const uint32_t num_ifaces = iface_list->Size();
137   Handle<mirror::Class> class_array_class = hs.NewHandle(GetClassArrayClass(soa.Self()));
138   Handle<mirror::ObjectArray<mirror::Class>> ifaces = hs.NewHandle(
139       mirror::ObjectArray<mirror::Class>::Alloc(soa.Self(), class_array_class.Get(), num_ifaces));
140   if (ifaces.IsNull()) {
141     DCHECK(soa.Self()->IsExceptionPending());
142     return nullptr;
143   }
144 
145   // Check that we aren't in an active transaction, we call SetWithoutChecks
146   // with kActiveTransaction == false.
147   DCHECK(!Runtime::Current()->IsActiveTransaction());
148 
149   MutableHandle<mirror::Class> interface(hs.NewHandle<mirror::Class>(nullptr));
150   for (uint32_t i = 0; i < num_ifaces; ++i) {
151     const dex::TypeIndex type_idx = iface_list->GetTypeItem(i).type_idx_;
152     interface.Assign(ClassLinker::LookupResolvedType(
153         type_idx, klass->GetDexCache(), klass->GetClassLoader()));
154     ifaces->SetWithoutChecks<false>(i, interface.Get());
155   }
156 
157   return soa.AddLocalReference<jobjectArray>(ifaces.Get());
158 }
159 
GetDeclaredFields(Thread * self,ObjPtr<mirror::Class> klass,bool public_only,bool force_resolve)160 static mirror::ObjectArray<mirror::Field>* GetDeclaredFields(
161     Thread* self, ObjPtr<mirror::Class> klass, bool public_only, bool force_resolve)
162       REQUIRES_SHARED(Locks::mutator_lock_) {
163   StackHandleScope<1> hs(self);
164   IterationRange<StrideIterator<ArtField>> ifields = klass->GetIFields();
165   IterationRange<StrideIterator<ArtField>> sfields = klass->GetSFields();
166   size_t array_size = klass->NumInstanceFields() + klass->NumStaticFields();
167   if (public_only) {
168     // Lets go subtract all the non public fields.
169     for (ArtField& field : ifields) {
170       if (!field.IsPublic()) {
171         --array_size;
172       }
173     }
174     for (ArtField& field : sfields) {
175       if (!field.IsPublic()) {
176         --array_size;
177       }
178     }
179   }
180   size_t array_idx = 0;
181   auto object_array = hs.NewHandle(mirror::ObjectArray<mirror::Field>::Alloc(
182       self, mirror::Field::ArrayClass(), array_size));
183   if (object_array == nullptr) {
184     return nullptr;
185   }
186   for (ArtField& field : ifields) {
187     if (!public_only || field.IsPublic()) {
188       auto* reflect_field = mirror::Field::CreateFromArtField<kRuntimePointerSize>(self,
189                                                                                    &field,
190                                                                                    force_resolve);
191       if (reflect_field == nullptr) {
192         if (kIsDebugBuild) {
193           self->AssertPendingException();
194         }
195         // Maybe null due to OOME or type resolving exception.
196         return nullptr;
197       }
198       object_array->SetWithoutChecks<false>(array_idx++, reflect_field);
199     }
200   }
201   for (ArtField& field : sfields) {
202     if (!public_only || field.IsPublic()) {
203       auto* reflect_field = mirror::Field::CreateFromArtField<kRuntimePointerSize>(self,
204                                                                                    &field,
205                                                                                    force_resolve);
206       if (reflect_field == nullptr) {
207         if (kIsDebugBuild) {
208           self->AssertPendingException();
209         }
210         return nullptr;
211       }
212       object_array->SetWithoutChecks<false>(array_idx++, reflect_field);
213     }
214   }
215   DCHECK_EQ(array_idx, array_size);
216   return object_array.Get();
217 }
218 
Class_getDeclaredFieldsUnchecked(JNIEnv * env,jobject javaThis,jboolean publicOnly)219 static jobjectArray Class_getDeclaredFieldsUnchecked(JNIEnv* env, jobject javaThis,
220                                                      jboolean publicOnly) {
221   ScopedFastNativeObjectAccess soa(env);
222   return soa.AddLocalReference<jobjectArray>(
223       GetDeclaredFields(soa.Self(), DecodeClass(soa, javaThis), publicOnly != JNI_FALSE, false));
224 }
225 
Class_getDeclaredFields(JNIEnv * env,jobject javaThis)226 static jobjectArray Class_getDeclaredFields(JNIEnv* env, jobject javaThis) {
227   ScopedFastNativeObjectAccess soa(env);
228   return soa.AddLocalReference<jobjectArray>(
229       GetDeclaredFields(soa.Self(), DecodeClass(soa, javaThis), false, true));
230 }
231 
Class_getPublicDeclaredFields(JNIEnv * env,jobject javaThis)232 static jobjectArray Class_getPublicDeclaredFields(JNIEnv* env, jobject javaThis) {
233   ScopedFastNativeObjectAccess soa(env);
234   return soa.AddLocalReference<jobjectArray>(
235       GetDeclaredFields(soa.Self(), DecodeClass(soa, javaThis), true, true));
236 }
237 
238 // Performs a binary search through an array of fields, TODO: Is this fast enough if we don't use
239 // the dex cache for lookups? I think CompareModifiedUtf8ToUtf16AsCodePointValues should be fairly
240 // fast.
FindFieldByName(ObjPtr<mirror::String> name,LengthPrefixedArray<ArtField> * fields)241 ALWAYS_INLINE static inline ArtField* FindFieldByName(ObjPtr<mirror::String> name,
242                                                       LengthPrefixedArray<ArtField>* fields)
243     REQUIRES_SHARED(Locks::mutator_lock_) {
244   if (fields == nullptr) {
245     return nullptr;
246   }
247   size_t low = 0;
248   size_t high = fields->size();
249   const bool is_name_compressed = name->IsCompressed();
250   const uint16_t* const data = (is_name_compressed) ? nullptr : name->GetValue();
251   const uint8_t* const data_compressed = (is_name_compressed) ? name->GetValueCompressed()
252                                                               : nullptr;
253   const size_t length = name->GetLength();
254   while (low < high) {
255     auto mid = (low + high) / 2;
256     ArtField& field = fields->At(mid);
257     int result = 0;
258     if (is_name_compressed) {
259       size_t field_length = strlen(field.GetName());
260       size_t min_size = (length < field_length) ? length : field_length;
261       result = memcmp(field.GetName(), data_compressed, min_size);
262       if (result == 0) {
263         result = field_length - length;
264       }
265     } else {
266       result = CompareModifiedUtf8ToUtf16AsCodePointValues(field.GetName(), data, length);
267     }
268     // Alternate approach, only a few % faster at the cost of more allocations.
269     // int result = field->GetStringName(self, true)->CompareTo(name);
270     if (result < 0) {
271       low = mid + 1;
272     } else if (result > 0) {
273       high = mid;
274     } else {
275       return &field;
276     }
277   }
278   if (kIsDebugBuild) {
279     for (ArtField& field : MakeIterationRangeFromLengthPrefixedArray(fields)) {
280       CHECK_NE(field.GetName(), name->ToModifiedUtf8());
281     }
282   }
283   return nullptr;
284 }
285 
GetDeclaredField(Thread * self,ObjPtr<mirror::Class> c,ObjPtr<mirror::String> name)286 ALWAYS_INLINE static inline mirror::Field* GetDeclaredField(Thread* self,
287                                                             ObjPtr<mirror::Class> c,
288                                                             ObjPtr<mirror::String> name)
289     REQUIRES_SHARED(Locks::mutator_lock_) {
290   ArtField* art_field = FindFieldByName(name, c->GetIFieldsPtr());
291   if (art_field != nullptr) {
292     return mirror::Field::CreateFromArtField<kRuntimePointerSize>(self, art_field, true);
293   }
294   art_field = FindFieldByName(name, c->GetSFieldsPtr());
295   if (art_field != nullptr) {
296     return mirror::Field::CreateFromArtField<kRuntimePointerSize>(self, art_field, true);
297   }
298   return nullptr;
299 }
300 
GetPublicFieldRecursive(Thread * self,ObjPtr<mirror::Class> clazz,ObjPtr<mirror::String> name)301 static mirror::Field* GetPublicFieldRecursive(
302     Thread* self, ObjPtr<mirror::Class> clazz, ObjPtr<mirror::String> name)
303     REQUIRES_SHARED(Locks::mutator_lock_) {
304   DCHECK(clazz != nullptr);
305   DCHECK(name != nullptr);
306   DCHECK(self != nullptr);
307 
308   StackHandleScope<2> hs(self);
309   MutableHandle<mirror::Class> h_clazz(hs.NewHandle(clazz));
310   Handle<mirror::String> h_name(hs.NewHandle(name));
311 
312   // We search the current class, its direct interfaces then its superclass.
313   while (h_clazz != nullptr) {
314     mirror::Field* result = GetDeclaredField(self, h_clazz.Get(), h_name.Get());
315     if ((result != nullptr) && (result->GetAccessFlags() & kAccPublic)) {
316       return result;
317     } else if (UNLIKELY(self->IsExceptionPending())) {
318       // Something went wrong. Bail out.
319       return nullptr;
320     }
321 
322     uint32_t num_direct_interfaces = h_clazz->NumDirectInterfaces();
323     for (uint32_t i = 0; i < num_direct_interfaces; i++) {
324       ObjPtr<mirror::Class> iface = mirror::Class::ResolveDirectInterface(self, h_clazz, i);
325       if (UNLIKELY(iface == nullptr)) {
326         self->AssertPendingException();
327         return nullptr;
328       }
329       result = GetPublicFieldRecursive(self, iface, h_name.Get());
330       if (result != nullptr) {
331         DCHECK(result->GetAccessFlags() & kAccPublic);
332         return result;
333       } else if (UNLIKELY(self->IsExceptionPending())) {
334         // Something went wrong. Bail out.
335         return nullptr;
336       }
337     }
338 
339     // We don't try the superclass if we are an interface.
340     if (h_clazz->IsInterface()) {
341       break;
342     }
343 
344     // Get the next class.
345     h_clazz.Assign(h_clazz->GetSuperClass());
346   }
347   return nullptr;
348 }
349 
Class_getPublicFieldRecursive(JNIEnv * env,jobject javaThis,jstring name)350 static jobject Class_getPublicFieldRecursive(JNIEnv* env, jobject javaThis, jstring name) {
351   ScopedFastNativeObjectAccess soa(env);
352   auto name_string = soa.Decode<mirror::String>(name);
353   if (UNLIKELY(name_string == nullptr)) {
354     ThrowNullPointerException("name == null");
355     return nullptr;
356   }
357   return soa.AddLocalReference<jobject>(
358       GetPublicFieldRecursive(soa.Self(), DecodeClass(soa, javaThis), name_string));
359 }
360 
Class_getDeclaredField(JNIEnv * env,jobject javaThis,jstring name)361 static jobject Class_getDeclaredField(JNIEnv* env, jobject javaThis, jstring name) {
362   ScopedFastNativeObjectAccess soa(env);
363   StackHandleScope<3> hs(soa.Self());
364   Handle<mirror::String> h_string = hs.NewHandle(soa.Decode<mirror::String>(name));
365   if (h_string == nullptr) {
366     ThrowNullPointerException("name == null");
367     return nullptr;
368   }
369   Handle<mirror::Class> h_klass = hs.NewHandle(DecodeClass(soa, javaThis));
370   Handle<mirror::Field> result =
371       hs.NewHandle(GetDeclaredField(soa.Self(), h_klass.Get(), h_string.Get()));
372   if (result == nullptr) {
373     std::string name_str = h_string->ToModifiedUtf8();
374     if (name_str == "value" && h_klass->IsStringClass()) {
375       // We log the error for this specific case, as the user might just swallow the exception.
376       // This helps diagnose crashes when applications rely on the String#value field being
377       // there.
378       // Also print on the error stream to test it through run-test.
379       std::string message("The String#value field is not present on Android versions >= 6.0");
380       LOG(ERROR) << message;
381       std::cerr << message << std::endl;
382     }
383     // We may have a pending exception if we failed to resolve.
384     if (!soa.Self()->IsExceptionPending()) {
385       ThrowNoSuchFieldException(h_klass.Get(), name_str.c_str());
386     }
387     return nullptr;
388   }
389   return soa.AddLocalReference<jobject>(result.Get());
390 }
391 
Class_getDeclaredConstructorInternal(JNIEnv * env,jobject javaThis,jobjectArray args)392 static jobject Class_getDeclaredConstructorInternal(
393     JNIEnv* env, jobject javaThis, jobjectArray args) {
394   ScopedFastNativeObjectAccess soa(env);
395   DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize);
396   DCHECK(!Runtime::Current()->IsActiveTransaction());
397   ObjPtr<mirror::Constructor> result =
398       mirror::Class::GetDeclaredConstructorInternal<kRuntimePointerSize, false>(
399       soa.Self(),
400       DecodeClass(soa, javaThis),
401       soa.Decode<mirror::ObjectArray<mirror::Class>>(args));
402   return soa.AddLocalReference<jobject>(result);
403 }
404 
MethodMatchesConstructor(ArtMethod * m,bool public_only)405 static ALWAYS_INLINE inline bool MethodMatchesConstructor(ArtMethod* m, bool public_only)
406     REQUIRES_SHARED(Locks::mutator_lock_) {
407   DCHECK(m != nullptr);
408   return (!public_only || m->IsPublic()) && !m->IsStatic() && m->IsConstructor();
409 }
410 
Class_getDeclaredConstructorsInternal(JNIEnv * env,jobject javaThis,jboolean publicOnly)411 static jobjectArray Class_getDeclaredConstructorsInternal(
412     JNIEnv* env, jobject javaThis, jboolean publicOnly) {
413   ScopedFastNativeObjectAccess soa(env);
414   StackHandleScope<2> hs(soa.Self());
415   Handle<mirror::Class> h_klass = hs.NewHandle(DecodeClass(soa, javaThis));
416   size_t constructor_count = 0;
417   // Two pass approach for speed.
418   for (auto& m : h_klass->GetDirectMethods(kRuntimePointerSize)) {
419     constructor_count += MethodMatchesConstructor(&m, publicOnly != JNI_FALSE) ? 1u : 0u;
420   }
421   auto h_constructors = hs.NewHandle(mirror::ObjectArray<mirror::Constructor>::Alloc(
422       soa.Self(), mirror::Constructor::ArrayClass(), constructor_count));
423   if (UNLIKELY(h_constructors == nullptr)) {
424     soa.Self()->AssertPendingException();
425     return nullptr;
426   }
427   constructor_count = 0;
428   for (auto& m : h_klass->GetDirectMethods(kRuntimePointerSize)) {
429     if (MethodMatchesConstructor(&m, publicOnly != JNI_FALSE)) {
430       DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize);
431       DCHECK(!Runtime::Current()->IsActiveTransaction());
432       auto* constructor = mirror::Constructor::CreateFromArtMethod<kRuntimePointerSize, false>(
433           soa.Self(), &m);
434       if (UNLIKELY(constructor == nullptr)) {
435         soa.Self()->AssertPendingOOMException();
436         return nullptr;
437       }
438       h_constructors->SetWithoutChecks<false>(constructor_count++, constructor);
439     }
440   }
441   return soa.AddLocalReference<jobjectArray>(h_constructors.Get());
442 }
443 
Class_getDeclaredMethodInternal(JNIEnv * env,jobject javaThis,jobject name,jobjectArray args)444 static jobject Class_getDeclaredMethodInternal(JNIEnv* env, jobject javaThis,
445                                                jobject name, jobjectArray args) {
446   ScopedFastNativeObjectAccess soa(env);
447   DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize);
448   DCHECK(!Runtime::Current()->IsActiveTransaction());
449   ObjPtr<mirror::Method> result =
450       mirror::Class::GetDeclaredMethodInternal<kRuntimePointerSize, false>(
451           soa.Self(),
452           DecodeClass(soa, javaThis),
453           soa.Decode<mirror::String>(name),
454           soa.Decode<mirror::ObjectArray<mirror::Class>>(args));
455   return soa.AddLocalReference<jobject>(result);
456 }
457 
Class_getDeclaredMethodsUnchecked(JNIEnv * env,jobject javaThis,jboolean publicOnly)458 static jobjectArray Class_getDeclaredMethodsUnchecked(JNIEnv* env, jobject javaThis,
459                                                       jboolean publicOnly) {
460   ScopedFastNativeObjectAccess soa(env);
461   StackHandleScope<2> hs(soa.Self());
462   Handle<mirror::Class> klass = hs.NewHandle(DecodeClass(soa, javaThis));
463   size_t num_methods = 0;
464   for (auto& m : klass->GetDeclaredMethods(kRuntimePointerSize)) {
465     auto modifiers = m.GetAccessFlags();
466     // Add non-constructor declared methods.
467     if ((publicOnly == JNI_FALSE || (modifiers & kAccPublic) != 0) &&
468         (modifiers & kAccConstructor) == 0) {
469       ++num_methods;
470     }
471   }
472   auto ret = hs.NewHandle(mirror::ObjectArray<mirror::Method>::Alloc(
473       soa.Self(), mirror::Method::ArrayClass(), num_methods));
474   if (ret == nullptr) {
475     soa.Self()->AssertPendingOOMException();
476     return nullptr;
477   }
478   num_methods = 0;
479   for (auto& m : klass->GetDeclaredMethods(kRuntimePointerSize)) {
480     auto modifiers = m.GetAccessFlags();
481     if ((publicOnly == JNI_FALSE || (modifiers & kAccPublic) != 0) &&
482         (modifiers & kAccConstructor) == 0) {
483       DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize);
484       DCHECK(!Runtime::Current()->IsActiveTransaction());
485       auto* method =
486           mirror::Method::CreateFromArtMethod<kRuntimePointerSize, false>(soa.Self(), &m);
487       if (method == nullptr) {
488         soa.Self()->AssertPendingException();
489         return nullptr;
490       }
491       ret->SetWithoutChecks<false>(num_methods++, method);
492     }
493   }
494   return soa.AddLocalReference<jobjectArray>(ret.Get());
495 }
496 
Class_getDeclaredAnnotation(JNIEnv * env,jobject javaThis,jclass annotationClass)497 static jobject Class_getDeclaredAnnotation(JNIEnv* env, jobject javaThis, jclass annotationClass) {
498   ScopedFastNativeObjectAccess soa(env);
499   StackHandleScope<2> hs(soa.Self());
500   Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
501 
502   // Handle public contract to throw NPE if the "annotationClass" argument was null.
503   if (UNLIKELY(annotationClass == nullptr)) {
504     ThrowNullPointerException("annotationClass");
505     return nullptr;
506   }
507 
508   if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
509     return nullptr;
510   }
511   Handle<mirror::Class> annotation_class(hs.NewHandle(soa.Decode<mirror::Class>(annotationClass)));
512   return soa.AddLocalReference<jobject>(
513       annotations::GetAnnotationForClass(klass, annotation_class));
514 }
515 
Class_getDeclaredAnnotations(JNIEnv * env,jobject javaThis)516 static jobjectArray Class_getDeclaredAnnotations(JNIEnv* env, jobject javaThis) {
517   ScopedFastNativeObjectAccess soa(env);
518   StackHandleScope<1> hs(soa.Self());
519   Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
520   if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
521     // Return an empty array instead of a null pointer.
522     ObjPtr<mirror::Class>  annotation_array_class =
523         soa.Decode<mirror::Class>(WellKnownClasses::java_lang_annotation_Annotation__array);
524     mirror::ObjectArray<mirror::Object>* empty_array =
525         mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(),
526                                                    annotation_array_class.Ptr(),
527                                                    0);
528     return soa.AddLocalReference<jobjectArray>(empty_array);
529   }
530   return soa.AddLocalReference<jobjectArray>(annotations::GetAnnotationsForClass(klass));
531 }
532 
Class_getDeclaredClasses(JNIEnv * env,jobject javaThis)533 static jobjectArray Class_getDeclaredClasses(JNIEnv* env, jobject javaThis) {
534   ScopedFastNativeObjectAccess soa(env);
535   StackHandleScope<1> hs(soa.Self());
536   Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
537   mirror::ObjectArray<mirror::Class>* classes = nullptr;
538   if (!klass->IsProxyClass() && klass->GetDexCache() != nullptr) {
539     classes = annotations::GetDeclaredClasses(klass);
540   }
541   if (classes == nullptr) {
542     // Return an empty array instead of a null pointer.
543     if (soa.Self()->IsExceptionPending()) {
544       // Pending exception from GetDeclaredClasses.
545       return nullptr;
546     }
547     ObjPtr<mirror::Class> class_array_class = GetClassArrayClass(soa.Self());
548     if (class_array_class == nullptr) {
549       return nullptr;
550     }
551     ObjPtr<mirror::ObjectArray<mirror::Class>> empty_array =
552         mirror::ObjectArray<mirror::Class>::Alloc(soa.Self(), class_array_class, 0);
553     return soa.AddLocalReference<jobjectArray>(empty_array);
554   }
555   return soa.AddLocalReference<jobjectArray>(classes);
556 }
557 
Class_getEnclosingClass(JNIEnv * env,jobject javaThis)558 static jclass Class_getEnclosingClass(JNIEnv* env, jobject javaThis) {
559   ScopedFastNativeObjectAccess soa(env);
560   StackHandleScope<1> hs(soa.Self());
561   Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
562   if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
563     return nullptr;
564   }
565   return soa.AddLocalReference<jclass>(annotations::GetEnclosingClass(klass));
566 }
567 
Class_getEnclosingConstructorNative(JNIEnv * env,jobject javaThis)568 static jobject Class_getEnclosingConstructorNative(JNIEnv* env, jobject javaThis) {
569   ScopedFastNativeObjectAccess soa(env);
570   StackHandleScope<1> hs(soa.Self());
571   Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
572   if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
573     return nullptr;
574   }
575   ObjPtr<mirror::Object> method = annotations::GetEnclosingMethod(klass);
576   if (method != nullptr) {
577     if (soa.Decode<mirror::Class>(WellKnownClasses::java_lang_reflect_Constructor) ==
578         method->GetClass()) {
579       return soa.AddLocalReference<jobject>(method);
580     }
581   }
582   return nullptr;
583 }
584 
Class_getEnclosingMethodNative(JNIEnv * env,jobject javaThis)585 static jobject Class_getEnclosingMethodNative(JNIEnv* env, jobject javaThis) {
586   ScopedFastNativeObjectAccess soa(env);
587   StackHandleScope<1> hs(soa.Self());
588   Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
589   if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
590     return nullptr;
591   }
592   ObjPtr<mirror::Object> method = annotations::GetEnclosingMethod(klass);
593   if (method != nullptr) {
594     if (soa.Decode<mirror::Class>(WellKnownClasses::java_lang_reflect_Method) ==
595         method->GetClass()) {
596       return soa.AddLocalReference<jobject>(method);
597     }
598   }
599   return nullptr;
600 }
601 
Class_getInnerClassFlags(JNIEnv * env,jobject javaThis,jint defaultValue)602 static jint Class_getInnerClassFlags(JNIEnv* env, jobject javaThis, jint defaultValue) {
603   ScopedFastNativeObjectAccess soa(env);
604   StackHandleScope<1> hs(soa.Self());
605   Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
606   return mirror::Class::GetInnerClassFlags(klass, defaultValue);
607 }
608 
Class_getInnerClassName(JNIEnv * env,jobject javaThis)609 static jstring Class_getInnerClassName(JNIEnv* env, jobject javaThis) {
610   ScopedFastNativeObjectAccess soa(env);
611   StackHandleScope<1> hs(soa.Self());
612   Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
613   if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
614     return nullptr;
615   }
616   mirror::String* class_name = nullptr;
617   if (!annotations::GetInnerClass(klass, &class_name)) {
618     return nullptr;
619   }
620   return soa.AddLocalReference<jstring>(class_name);
621 }
622 
Class_getSignatureAnnotation(JNIEnv * env,jobject javaThis)623 static jobjectArray Class_getSignatureAnnotation(JNIEnv* env, jobject javaThis) {
624   ScopedFastNativeObjectAccess soa(env);
625   StackHandleScope<1> hs(soa.Self());
626   Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
627   if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
628     return nullptr;
629   }
630   return soa.AddLocalReference<jobjectArray>(
631       annotations::GetSignatureAnnotationForClass(klass));
632 }
633 
Class_isAnonymousClass(JNIEnv * env,jobject javaThis)634 static jboolean Class_isAnonymousClass(JNIEnv* env, jobject javaThis) {
635   ScopedFastNativeObjectAccess soa(env);
636   StackHandleScope<1> hs(soa.Self());
637   Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
638   if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
639     return false;
640   }
641   mirror::String* class_name = nullptr;
642   if (!annotations::GetInnerClass(klass, &class_name)) {
643     return false;
644   }
645   return class_name == nullptr;
646 }
647 
Class_isDeclaredAnnotationPresent(JNIEnv * env,jobject javaThis,jclass annotationType)648 static jboolean Class_isDeclaredAnnotationPresent(JNIEnv* env, jobject javaThis,
649                                                   jclass annotationType) {
650   ScopedFastNativeObjectAccess soa(env);
651   StackHandleScope<2> hs(soa.Self());
652   Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
653   if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
654     return false;
655   }
656   Handle<mirror::Class> annotation_class(hs.NewHandle(soa.Decode<mirror::Class>(annotationType)));
657   return annotations::IsClassAnnotationPresent(klass, annotation_class);
658 }
659 
Class_getDeclaringClass(JNIEnv * env,jobject javaThis)660 static jclass Class_getDeclaringClass(JNIEnv* env, jobject javaThis) {
661   ScopedFastNativeObjectAccess soa(env);
662   StackHandleScope<1> hs(soa.Self());
663   Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
664   if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
665     return nullptr;
666   }
667   // Return null for anonymous classes.
668   if (Class_isAnonymousClass(env, javaThis)) {
669     return nullptr;
670   }
671   return soa.AddLocalReference<jclass>(annotations::GetDeclaringClass(klass));
672 }
673 
Class_newInstance(JNIEnv * env,jobject javaThis)674 static jobject Class_newInstance(JNIEnv* env, jobject javaThis) {
675   ScopedFastNativeObjectAccess soa(env);
676   StackHandleScope<4> hs(soa.Self());
677   Handle<mirror::Class> klass = hs.NewHandle(DecodeClass(soa, javaThis));
678   if (UNLIKELY(klass->GetPrimitiveType() != 0 || klass->IsInterface() || klass->IsArrayClass() ||
679                klass->IsAbstract())) {
680     soa.Self()->ThrowNewExceptionF("Ljava/lang/InstantiationException;",
681                                    "%s cannot be instantiated",
682                                    klass->PrettyClass().c_str());
683     return nullptr;
684   }
685   auto caller = hs.NewHandle<mirror::Class>(nullptr);
686   // Verify that we can access the class.
687   if (!klass->IsPublic()) {
688     caller.Assign(GetCallingClass(soa.Self(), 1));
689     if (caller != nullptr && !caller->CanAccess(klass.Get())) {
690       soa.Self()->ThrowNewExceptionF(
691           "Ljava/lang/IllegalAccessException;", "%s is not accessible from %s",
692           klass->PrettyClass().c_str(), caller->PrettyClass().c_str());
693       return nullptr;
694     }
695   }
696   auto* constructor = klass->GetDeclaredConstructor(
697       soa.Self(),
698       ScopedNullHandle<mirror::ObjectArray<mirror::Class>>(),
699       kRuntimePointerSize);
700   if (UNLIKELY(constructor == nullptr)) {
701     soa.Self()->ThrowNewExceptionF("Ljava/lang/InstantiationException;",
702                                    "%s has no zero argument constructor",
703                                    klass->PrettyClass().c_str());
704     return nullptr;
705   }
706   // Invoke the string allocator to return an empty string for the string class.
707   if (klass->IsStringClass()) {
708     gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
709     ObjPtr<mirror::Object> obj = mirror::String::AllocEmptyString<true>(soa.Self(), allocator_type);
710     if (UNLIKELY(soa.Self()->IsExceptionPending())) {
711       return nullptr;
712     } else {
713       return soa.AddLocalReference<jobject>(obj);
714     }
715   }
716   auto receiver = hs.NewHandle(klass->AllocObject(soa.Self()));
717   if (UNLIKELY(receiver == nullptr)) {
718     soa.Self()->AssertPendingOOMException();
719     return nullptr;
720   }
721   // Verify that we can access the constructor.
722   auto* declaring_class = constructor->GetDeclaringClass();
723   if (!constructor->IsPublic()) {
724     if (caller == nullptr) {
725       caller.Assign(GetCallingClass(soa.Self(), 1));
726     }
727     if (UNLIKELY(caller != nullptr && !VerifyAccess(receiver.Get(),
728                                                           declaring_class,
729                                                           constructor->GetAccessFlags(),
730                                                           caller.Get()))) {
731       soa.Self()->ThrowNewExceptionF(
732           "Ljava/lang/IllegalAccessException;", "%s is not accessible from %s",
733           constructor->PrettyMethod().c_str(), caller->PrettyClass().c_str());
734       return nullptr;
735     }
736   }
737   // Ensure that we are initialized.
738   if (UNLIKELY(!declaring_class->IsInitialized())) {
739     if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(
740         soa.Self(), hs.NewHandle(declaring_class), true, true)) {
741       soa.Self()->AssertPendingException();
742       return nullptr;
743     }
744   }
745   // Invoke the constructor.
746   JValue result;
747   uint32_t args[1] = { static_cast<uint32_t>(reinterpret_cast<uintptr_t>(receiver.Get())) };
748   constructor->Invoke(soa.Self(), args, sizeof(args), &result, "V");
749   if (UNLIKELY(soa.Self()->IsExceptionPending())) {
750     return nullptr;
751   }
752   // Constructors are ()V methods, so we shouldn't touch the result of InvokeMethod.
753   return soa.AddLocalReference<jobject>(receiver.Get());
754 }
755 
756 static JNINativeMethod gMethods[] = {
757   FAST_NATIVE_METHOD(Class, classForName,
758                 "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;"),
759   FAST_NATIVE_METHOD(Class, getDeclaredAnnotation,
760                 "(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;"),
761   FAST_NATIVE_METHOD(Class, getDeclaredAnnotations, "()[Ljava/lang/annotation/Annotation;"),
762   FAST_NATIVE_METHOD(Class, getDeclaredClasses, "()[Ljava/lang/Class;"),
763   FAST_NATIVE_METHOD(Class, getDeclaredConstructorInternal,
764                 "([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;"),
765   FAST_NATIVE_METHOD(Class, getDeclaredConstructorsInternal, "(Z)[Ljava/lang/reflect/Constructor;"),
766   FAST_NATIVE_METHOD(Class, getDeclaredField, "(Ljava/lang/String;)Ljava/lang/reflect/Field;"),
767   FAST_NATIVE_METHOD(Class, getPublicFieldRecursive, "(Ljava/lang/String;)Ljava/lang/reflect/Field;"),
768   FAST_NATIVE_METHOD(Class, getDeclaredFields, "()[Ljava/lang/reflect/Field;"),
769   FAST_NATIVE_METHOD(Class, getDeclaredFieldsUnchecked, "(Z)[Ljava/lang/reflect/Field;"),
770   FAST_NATIVE_METHOD(Class, getDeclaredMethodInternal,
771                 "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;"),
772   FAST_NATIVE_METHOD(Class, getDeclaredMethodsUnchecked,
773                 "(Z)[Ljava/lang/reflect/Method;"),
774   FAST_NATIVE_METHOD(Class, getDeclaringClass, "()Ljava/lang/Class;"),
775   FAST_NATIVE_METHOD(Class, getEnclosingClass, "()Ljava/lang/Class;"),
776   FAST_NATIVE_METHOD(Class, getEnclosingConstructorNative, "()Ljava/lang/reflect/Constructor;"),
777   FAST_NATIVE_METHOD(Class, getEnclosingMethodNative, "()Ljava/lang/reflect/Method;"),
778   FAST_NATIVE_METHOD(Class, getInnerClassFlags, "(I)I"),
779   FAST_NATIVE_METHOD(Class, getInnerClassName, "()Ljava/lang/String;"),
780   FAST_NATIVE_METHOD(Class, getInterfacesInternal, "()[Ljava/lang/Class;"),
781   FAST_NATIVE_METHOD(Class, getNameNative, "()Ljava/lang/String;"),
782   FAST_NATIVE_METHOD(Class, getPublicDeclaredFields, "()[Ljava/lang/reflect/Field;"),
783   FAST_NATIVE_METHOD(Class, getSignatureAnnotation, "()[Ljava/lang/String;"),
784   FAST_NATIVE_METHOD(Class, isAnonymousClass, "()Z"),
785   FAST_NATIVE_METHOD(Class, isDeclaredAnnotationPresent, "(Ljava/lang/Class;)Z"),
786   FAST_NATIVE_METHOD(Class, newInstance, "()Ljava/lang/Object;"),
787 };
788 
register_java_lang_Class(JNIEnv * env)789 void register_java_lang_Class(JNIEnv* env) {
790   REGISTER_NATIVE_METHODS("java/lang/Class");
791 }
792 
793 }  // namespace art
794