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_reflect_Field.h"
18 
19 #include "android-base/stringprintf.h"
20 #include "nativehelper/jni_macros.h"
21 
22 #include "art_field-inl.h"
23 #include "base/utils.h"
24 #include "class_linker-inl.h"
25 #include "class_linker.h"
26 #include "common_throws.h"
27 #include "dex/dex_file-inl.h"
28 #include "dex/dex_file_annotations.h"
29 #include "gc/reference_processor.h"
30 #include "jni/jni_internal.h"
31 #include "jvalue-inl.h"
32 #include "mirror/class-inl.h"
33 #include "mirror/field-inl.h"
34 #include "mirror/object_array-alloc-inl.h"
35 #include "native_util.h"
36 #include "reflection-inl.h"
37 #include "scoped_fast_native_object_access-inl.h"
38 #include "well_known_classes.h"
39 
40 namespace art {
41 
42 using android::base::StringPrintf;
43 
44 template<bool kIsSet>
VerifyFieldAccess(Thread * self,ObjPtr<mirror::Field> field,ObjPtr<mirror::Object> obj)45 ALWAYS_INLINE inline static bool VerifyFieldAccess(Thread* self,
46                                                    ObjPtr<mirror::Field> field,
47                                                    ObjPtr<mirror::Object> obj)
48     REQUIRES_SHARED(Locks::mutator_lock_) {
49   if (kIsSet && field->IsFinal()) {
50     ThrowIllegalAccessException(
51             StringPrintf("Cannot set %s field %s of class %s",
52                 PrettyJavaAccessFlags(field->GetAccessFlags()).c_str(),
53                 ArtField::PrettyField(field->GetArtField()).c_str(),
54                 field->GetDeclaringClass() == nullptr ? "null" :
55                     field->GetDeclaringClass()->PrettyClass().c_str()).c_str());
56     return false;
57   }
58   ObjPtr<mirror::Class> calling_class;
59   if (!VerifyAccess(self,
60                     obj,
61                     field->GetDeclaringClass(),
62                     field->GetAccessFlags(),
63                     &calling_class,
64                     1)) {
65     ThrowIllegalAccessException(
66             StringPrintf("Class %s cannot access %s field %s of class %s",
67                 calling_class == nullptr ? "null" : calling_class->PrettyClass().c_str(),
68                 PrettyJavaAccessFlags(field->GetAccessFlags()).c_str(),
69                 ArtField::PrettyField(field->GetArtField()).c_str(),
70                 field->GetDeclaringClass() == nullptr ? "null" :
71                     field->GetDeclaringClass()->PrettyClass().c_str()).c_str());
72     return false;
73   }
74   return true;
75 }
76 
77 template<bool kAllowReferences>
GetFieldValue(const ScopedFastNativeObjectAccess & soa,ObjPtr<mirror::Object> o,ObjPtr<mirror::Field> f,Primitive::Type field_type,JValue * value)78 ALWAYS_INLINE inline static bool GetFieldValue(const ScopedFastNativeObjectAccess& soa,
79                                                ObjPtr<mirror::Object> o,
80                                                ObjPtr<mirror::Field> f,
81                                                Primitive::Type field_type,
82                                                JValue* value)
83     REQUIRES_SHARED(Locks::mutator_lock_) {
84   DCHECK_EQ(value->GetJ(), INT64_C(0));
85   MemberOffset offset(f->GetOffset());
86   const bool is_volatile = f->IsVolatile();
87   switch (field_type) {
88     case Primitive::kPrimBoolean:
89       value->SetZ(is_volatile ? o->GetFieldBooleanVolatile(offset) : o->GetFieldBoolean(offset));
90       return true;
91     case Primitive::kPrimByte:
92       value->SetB(is_volatile ? o->GetFieldByteVolatile(offset) : o->GetFieldByte(offset));
93       return true;
94     case Primitive::kPrimChar:
95       value->SetC(is_volatile ? o->GetFieldCharVolatile(offset) : o->GetFieldChar(offset));
96       return true;
97     case Primitive::kPrimInt:
98     case Primitive::kPrimFloat:
99       value->SetI(is_volatile ? o->GetField32Volatile(offset) : o->GetField32(offset));
100       return true;
101     case Primitive::kPrimLong:
102     case Primitive::kPrimDouble:
103       value->SetJ(is_volatile ? o->GetField64Volatile(offset) : o->GetField64(offset));
104       return true;
105     case Primitive::kPrimShort:
106       value->SetS(is_volatile ? o->GetFieldShortVolatile(offset) : o->GetFieldShort(offset));
107       return true;
108     case Primitive::kPrimNot:
109       if (kAllowReferences) {
110         // We need to ensure that a Reference-type object's referent is fetched
111         // via GetReferent and not directly using a read-barrier (See b/174433134)
112         const uint32_t class_flags = o->GetClass()->GetClassFlags();
113         if (UNLIKELY((class_flags & mirror::kClassFlagReference) != 0 &&
114                      mirror::Reference::ReferentOffset() == offset)) {
115           // PhantomReference's get() always returns null.
116           value->SetL((class_flags & mirror::kClassFlagPhantomReference) != 0
117                           ? nullptr
118                           : Runtime::Current()->GetHeap()->GetReferenceProcessor()->GetReferent(
119                                   soa.Self(), o->AsReference()));
120         } else {
121           value->SetL(is_volatile ? o->GetFieldObjectVolatile<mirror::Object>(offset) :
122                       o->GetFieldObject<mirror::Object>(offset));
123         }
124         return true;
125       }
126       // Else break to report an error.
127       break;
128     case Primitive::kPrimVoid:
129       // Never okay.
130       break;
131   }
132   ThrowIllegalArgumentException(
133       StringPrintf("Not a primitive field: %s",
134                    ArtField::PrettyField(f->GetArtField()).c_str()).c_str());
135   return false;
136 }
137 
CheckReceiver(const ScopedFastNativeObjectAccess & soa,jobject j_rcvr,ObjPtr<mirror::Field> * f,ObjPtr<mirror::Object> * class_or_rcvr)138 ALWAYS_INLINE inline static bool CheckReceiver(const ScopedFastNativeObjectAccess& soa,
139                                                jobject j_rcvr,
140                                                ObjPtr<mirror::Field>* f,
141                                                ObjPtr<mirror::Object>* class_or_rcvr)
142     REQUIRES_SHARED(Locks::mutator_lock_) {
143   soa.Self()->AssertThreadSuspensionIsAllowable();
144   ObjPtr<mirror::Class> declaring_class = (*f)->GetDeclaringClass();
145   if ((*f)->IsStatic()) {
146     if (UNLIKELY(!declaring_class->IsVisiblyInitialized())) {
147       Thread* self = soa.Self();
148       StackHandleScope<2> hs(self);
149       HandleWrapperObjPtr<mirror::Field> h_f(hs.NewHandleWrapper(f));
150       HandleWrapperObjPtr<mirror::Class> h_klass(hs.NewHandleWrapper(&declaring_class));
151       if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized(
152                         self, h_klass, /*can_init_fields=*/ true, /*can_init_parents=*/ true))) {
153         DCHECK(self->IsExceptionPending());
154         return false;
155       }
156       DCHECK(h_klass->IsInitializing());
157     }
158     *class_or_rcvr = declaring_class;
159     return true;
160   }
161   *class_or_rcvr = soa.Decode<mirror::Object>(j_rcvr);
162   if (!VerifyObjectIsClass(*class_or_rcvr, declaring_class)) {
163     DCHECK(soa.Self()->IsExceptionPending());
164     return false;
165   }
166   return true;
167 }
168 
Field_get(JNIEnv * env,jobject javaField,jobject javaObj)169 static jobject Field_get(JNIEnv* env, jobject javaField, jobject javaObj) {
170   ScopedFastNativeObjectAccess soa(env);
171   ObjPtr<mirror::Field> f = soa.Decode<mirror::Field>(javaField);
172   ObjPtr<mirror::Object> o;
173   if (!CheckReceiver(soa, javaObj, &f, &o)) {
174     DCHECK(soa.Self()->IsExceptionPending());
175     return nullptr;
176   }
177   // If field is not set to be accessible, verify it can be accessed by the caller.
178   if (!f->IsAccessible() && !VerifyFieldAccess<false>(soa.Self(), f, o)) {
179     DCHECK(soa.Self()->IsExceptionPending());
180     return nullptr;
181   }
182   // We now don't expect suspension unless an exception is thrown.
183   // Get the field's value, boxing if necessary.
184   Primitive::Type field_type = f->GetTypeAsPrimitiveType();
185   JValue value;
186   if (!GetFieldValue<true>(soa, o, f, field_type, &value)) {
187     DCHECK(soa.Self()->IsExceptionPending());
188     return nullptr;
189   }
190   return soa.AddLocalReference<jobject>(BoxPrimitive(field_type, value));
191 }
192 
193 template<Primitive::Type kPrimitiveType>
GetPrimitiveField(JNIEnv * env,jobject javaField,jobject javaObj)194 ALWAYS_INLINE inline static JValue GetPrimitiveField(JNIEnv* env,
195                                                      jobject javaField,
196                                                      jobject javaObj) {
197   ScopedFastNativeObjectAccess soa(env);
198   ObjPtr<mirror::Field> f = soa.Decode<mirror::Field>(javaField);
199   ObjPtr<mirror::Object> o;
200   if (!CheckReceiver(soa, javaObj, &f, &o)) {
201     DCHECK(soa.Self()->IsExceptionPending());
202     return JValue();
203   }
204 
205   // If field is not set to be accessible, verify it can be accessed by the caller.
206   if (!f->IsAccessible() && !VerifyFieldAccess<false>(soa.Self(), f, o)) {
207     DCHECK(soa.Self()->IsExceptionPending());
208     return JValue();
209   }
210 
211   // We now don't expect suspension unless an exception is thrown.
212   // Read the value.
213   Primitive::Type field_type = f->GetTypeAsPrimitiveType();
214   JValue field_value;
215   if (field_type == kPrimitiveType) {
216     // This if statement should get optimized out since we only pass in valid primitive types.
217     if (UNLIKELY(!GetFieldValue<false>(soa, o, f, kPrimitiveType, &field_value))) {
218       DCHECK(soa.Self()->IsExceptionPending());
219       return JValue();
220     }
221     return field_value;
222   }
223   if (!GetFieldValue<false>(soa, o, f, field_type, &field_value)) {
224     DCHECK(soa.Self()->IsExceptionPending());
225     return JValue();
226   }
227   // Widen it if necessary (and possible).
228   JValue wide_value;
229   if (!ConvertPrimitiveValue(false, field_type, kPrimitiveType, field_value,
230                              &wide_value)) {
231     DCHECK(soa.Self()->IsExceptionPending());
232     return JValue();
233   }
234   return wide_value;
235 }
236 
Field_getBoolean(JNIEnv * env,jobject javaField,jobject javaObj)237 static jboolean Field_getBoolean(JNIEnv* env, jobject javaField, jobject javaObj) {
238   return GetPrimitiveField<Primitive::kPrimBoolean>(env, javaField, javaObj).GetZ();
239 }
240 
Field_getByte(JNIEnv * env,jobject javaField,jobject javaObj)241 static jbyte Field_getByte(JNIEnv* env, jobject javaField, jobject javaObj) {
242   return GetPrimitiveField<Primitive::kPrimByte>(env, javaField, javaObj).GetB();
243 }
244 
Field_getChar(JNIEnv * env,jobject javaField,jobject javaObj)245 static jchar Field_getChar(JNIEnv* env, jobject javaField, jobject javaObj) {
246   return GetPrimitiveField<Primitive::kPrimChar>(env, javaField, javaObj).GetC();
247 }
248 
Field_getDouble(JNIEnv * env,jobject javaField,jobject javaObj)249 static jdouble Field_getDouble(JNIEnv* env, jobject javaField, jobject javaObj) {
250   return GetPrimitiveField<Primitive::kPrimDouble>(env, javaField, javaObj).GetD();
251 }
252 
Field_getFloat(JNIEnv * env,jobject javaField,jobject javaObj)253 static jfloat Field_getFloat(JNIEnv* env, jobject javaField, jobject javaObj) {
254   return GetPrimitiveField<Primitive::kPrimFloat>(env, javaField, javaObj).GetF();
255 }
256 
Field_getInt(JNIEnv * env,jobject javaField,jobject javaObj)257 static jint Field_getInt(JNIEnv* env, jobject javaField, jobject javaObj) {
258   return GetPrimitiveField<Primitive::kPrimInt>(env, javaField, javaObj).GetI();
259 }
260 
Field_getLong(JNIEnv * env,jobject javaField,jobject javaObj)261 static jlong Field_getLong(JNIEnv* env, jobject javaField, jobject javaObj) {
262   return GetPrimitiveField<Primitive::kPrimLong>(env, javaField, javaObj).GetJ();
263 }
264 
Field_getShort(JNIEnv * env,jobject javaField,jobject javaObj)265 static jshort Field_getShort(JNIEnv* env, jobject javaField, jobject javaObj) {
266   return GetPrimitiveField<Primitive::kPrimShort>(env, javaField, javaObj).GetS();
267 }
268 
SetFieldValue(ObjPtr<mirror::Object> o,ObjPtr<mirror::Field> f,Primitive::Type field_type,bool allow_references,const JValue & new_value)269 ALWAYS_INLINE inline static void SetFieldValue(ObjPtr<mirror::Object> o,
270                                                ObjPtr<mirror::Field> f,
271                                                Primitive::Type field_type,
272                                                bool allow_references,
273                                                const JValue& new_value)
274     REQUIRES_SHARED(Locks::mutator_lock_) {
275   DCHECK(f->GetDeclaringClass()->IsInitializing());
276   MemberOffset offset(f->GetOffset());
277   const bool is_volatile = f->IsVolatile();
278   switch (field_type) {
279   case Primitive::kPrimBoolean:
280     if (is_volatile) {
281       o->SetFieldBooleanVolatile<false>(offset, new_value.GetZ());
282     } else {
283       o->SetFieldBoolean<false>(offset, new_value.GetZ());
284     }
285     break;
286   case Primitive::kPrimByte:
287     if (is_volatile) {
288       o->SetFieldBooleanVolatile<false>(offset, new_value.GetB());
289     } else {
290       o->SetFieldBoolean<false>(offset, new_value.GetB());
291     }
292     break;
293   case Primitive::kPrimChar:
294     if (is_volatile) {
295       o->SetFieldCharVolatile<false>(offset, new_value.GetC());
296     } else {
297       o->SetFieldChar<false>(offset, new_value.GetC());
298     }
299     break;
300   case Primitive::kPrimInt:
301   case Primitive::kPrimFloat:
302     if (is_volatile) {
303       o->SetField32Volatile<false>(offset, new_value.GetI());
304     } else {
305       o->SetField32<false>(offset, new_value.GetI());
306     }
307     break;
308   case Primitive::kPrimLong:
309   case Primitive::kPrimDouble:
310     if (is_volatile) {
311       o->SetField64Volatile<false>(offset, new_value.GetJ());
312     } else {
313       o->SetField64<false>(offset, new_value.GetJ());
314     }
315     break;
316   case Primitive::kPrimShort:
317     if (is_volatile) {
318       o->SetFieldShortVolatile<false>(offset, new_value.GetS());
319     } else {
320       o->SetFieldShort<false>(offset, new_value.GetS());
321     }
322     break;
323   case Primitive::kPrimNot:
324     if (allow_references) {
325       if (is_volatile) {
326         o->SetFieldObjectVolatile<false>(offset, new_value.GetL());
327       } else {
328         o->SetFieldObject<false>(offset, new_value.GetL());
329       }
330       break;
331     }
332     // Else fall through to report an error.
333     FALLTHROUGH_INTENDED;
334   case Primitive::kPrimVoid:
335     // Never okay.
336     ThrowIllegalArgumentException(
337         StringPrintf("Not a primitive field: %s",
338                      ArtField::PrettyField(f->GetArtField()).c_str()).c_str());
339     return;
340   }
341 }
342 
Field_set(JNIEnv * env,jobject javaField,jobject javaObj,jobject javaValue)343 static void Field_set(JNIEnv* env, jobject javaField, jobject javaObj, jobject javaValue) {
344   ScopedFastNativeObjectAccess soa(env);
345   ObjPtr<mirror::Field> f = soa.Decode<mirror::Field>(javaField);
346   // Check that the receiver is non-null and an instance of the field's declaring class.
347   ObjPtr<mirror::Object> o;
348   if (!CheckReceiver(soa, javaObj, &f, &o)) {
349     DCHECK(soa.Self()->IsExceptionPending());
350     return;
351   }
352   ObjPtr<mirror::Class> field_type;
353   const char* field_type_descriptor = f->GetArtField()->GetTypeDescriptor();
354   Primitive::Type field_prim_type = Primitive::GetType(field_type_descriptor[0]);
355   if (field_prim_type == Primitive::kPrimNot) {
356     field_type = f->GetType();
357   } else {
358     field_type =
359         Runtime::Current()->GetClassLinker()->LookupPrimitiveClass(field_type_descriptor[0]);
360   }
361   DCHECK(field_type != nullptr) << field_type_descriptor;
362   // We now don't expect suspension unless an exception is thrown.
363   // Unbox the value, if necessary.
364   ObjPtr<mirror::Object> boxed_value = soa.Decode<mirror::Object>(javaValue);
365   JValue unboxed_value;
366   if (!UnboxPrimitiveForField(boxed_value,
367                               field_type,
368                               f->GetArtField(),
369                               &unboxed_value)) {
370     DCHECK(soa.Self()->IsExceptionPending());
371     return;
372   }
373   // If field is not set to be accessible, verify it can be accessed by the caller.
374   if (!f->IsAccessible() && !VerifyFieldAccess<true>(soa.Self(), f, o)) {
375     DCHECK(soa.Self()->IsExceptionPending());
376     return;
377   }
378   SetFieldValue(o, f, field_prim_type, true, unboxed_value);
379 }
380 
381 template<Primitive::Type kPrimitiveType>
SetPrimitiveField(JNIEnv * env,jobject javaField,jobject javaObj,const JValue & new_value)382 static void SetPrimitiveField(JNIEnv* env,
383                               jobject javaField,
384                               jobject javaObj,
385                               const JValue& new_value) {
386   ScopedFastNativeObjectAccess soa(env);
387   ObjPtr<mirror::Field> f = soa.Decode<mirror::Field>(javaField);
388   ObjPtr<mirror::Object> o;
389   if (!CheckReceiver(soa, javaObj, &f, &o)) {
390     return;
391   }
392   Primitive::Type field_type = f->GetTypeAsPrimitiveType();
393   if (UNLIKELY(field_type == Primitive::kPrimNot)) {
394     ThrowIllegalArgumentException(
395         StringPrintf("Not a primitive field: %s",
396                      ArtField::PrettyField(f->GetArtField()).c_str()).c_str());
397     return;
398   }
399 
400   // Widen the value if necessary (and possible).
401   JValue wide_value;
402   if (!ConvertPrimitiveValue(false, kPrimitiveType, field_type, new_value, &wide_value)) {
403     DCHECK(soa.Self()->IsExceptionPending());
404     return;
405   }
406 
407   // If field is not set to be accessible, verify it can be accessed by the caller.
408   if (!f->IsAccessible() && !VerifyFieldAccess<true>(soa.Self(), f, o)) {
409     DCHECK(soa.Self()->IsExceptionPending());
410     return;
411   }
412 
413   // Write the value.
414   SetFieldValue(o, f, field_type, false, wide_value);
415 }
416 
Field_setBoolean(JNIEnv * env,jobject javaField,jobject javaObj,jboolean z)417 static void Field_setBoolean(JNIEnv* env, jobject javaField, jobject javaObj, jboolean z) {
418   JValue value;
419   value.SetZ(z);
420   SetPrimitiveField<Primitive::kPrimBoolean>(env, javaField, javaObj, value);
421 }
422 
Field_setByte(JNIEnv * env,jobject javaField,jobject javaObj,jbyte b)423 static void Field_setByte(JNIEnv* env, jobject javaField, jobject javaObj, jbyte b) {
424   JValue value;
425   value.SetB(b);
426   SetPrimitiveField<Primitive::kPrimByte>(env, javaField, javaObj, value);
427 }
428 
Field_setChar(JNIEnv * env,jobject javaField,jobject javaObj,jchar c)429 static void Field_setChar(JNIEnv* env, jobject javaField, jobject javaObj, jchar c) {
430   JValue value;
431   value.SetC(c);
432   SetPrimitiveField<Primitive::kPrimChar>(env, javaField, javaObj, value);
433 }
434 
Field_setDouble(JNIEnv * env,jobject javaField,jobject javaObj,jdouble d)435 static void Field_setDouble(JNIEnv* env, jobject javaField, jobject javaObj, jdouble d) {
436   JValue value;
437   value.SetD(d);
438   SetPrimitiveField<Primitive::kPrimDouble>(env, javaField, javaObj, value);
439 }
440 
Field_setFloat(JNIEnv * env,jobject javaField,jobject javaObj,jfloat f)441 static void Field_setFloat(JNIEnv* env, jobject javaField, jobject javaObj, jfloat f) {
442   JValue value;
443   value.SetF(f);
444   SetPrimitiveField<Primitive::kPrimFloat>(env, javaField, javaObj, value);
445 }
446 
Field_setInt(JNIEnv * env,jobject javaField,jobject javaObj,jint i)447 static void Field_setInt(JNIEnv* env, jobject javaField, jobject javaObj, jint i) {
448   JValue value;
449   value.SetI(i);
450   SetPrimitiveField<Primitive::kPrimInt>(env, javaField, javaObj, value);
451 }
452 
Field_setLong(JNIEnv * env,jobject javaField,jobject javaObj,jlong j)453 static void Field_setLong(JNIEnv* env, jobject javaField, jobject javaObj, jlong j) {
454   JValue value;
455   value.SetJ(j);
456   SetPrimitiveField<Primitive::kPrimLong>(env, javaField, javaObj, value);
457 }
458 
Field_setShort(JNIEnv * env,jobject javaField,jobject javaObj,jshort s)459 static void Field_setShort(JNIEnv* env, jobject javaField, jobject javaObj, jshort s) {
460   JValue value;
461   value.SetS(s);
462   SetPrimitiveField<Primitive::kPrimShort>(env, javaField, javaObj, value);
463 }
464 
Field_getAnnotationNative(JNIEnv * env,jobject javaField,jclass annotationType)465 static jobject Field_getAnnotationNative(JNIEnv* env, jobject javaField, jclass annotationType) {
466   ScopedFastNativeObjectAccess soa(env);
467   StackHandleScope<1> hs(soa.Self());
468   ArtField* field = soa.Decode<mirror::Field>(javaField)->GetArtField();
469   if (field->GetDeclaringClass()->IsProxyClass()) {
470     return nullptr;
471   }
472   Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class>(annotationType)));
473   return soa.AddLocalReference<jobject>(annotations::GetAnnotationForField(field, klass));
474 }
475 
Field_getArtField(JNIEnv * env,jobject javaField)476 static jlong Field_getArtField(JNIEnv* env, jobject javaField) {
477   ScopedFastNativeObjectAccess soa(env);
478   ArtField* field = soa.Decode<mirror::Field>(javaField)->GetArtField();
479   return reinterpret_cast<jlong>(field);
480 }
481 
Field_getNameInternal(JNIEnv * env,jobject javaField)482 static jstring Field_getNameInternal(JNIEnv* env, jobject javaField) {
483   ScopedFastNativeObjectAccess soa(env);
484   ArtField* field = soa.Decode<mirror::Field>(javaField)->GetArtField();
485   return soa.AddLocalReference<jstring>(field->ResolveNameString());
486 }
487 
Field_getDeclaredAnnotations(JNIEnv * env,jobject javaField)488 static jobjectArray Field_getDeclaredAnnotations(JNIEnv* env, jobject javaField) {
489   ScopedFastNativeObjectAccess soa(env);
490   ArtField* field = soa.Decode<mirror::Field>(javaField)->GetArtField();
491   if (field->GetDeclaringClass()->IsProxyClass()) {
492     // Return an empty array instead of a null pointer.
493     ObjPtr<mirror::Class> annotation_array_class =
494         soa.Decode<mirror::Class>(WellKnownClasses::java_lang_annotation_Annotation__array);
495     ObjPtr<mirror::ObjectArray<mirror::Object>> empty_array =
496         mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), annotation_array_class, 0);
497     return soa.AddLocalReference<jobjectArray>(empty_array);
498   }
499   return soa.AddLocalReference<jobjectArray>(annotations::GetAnnotationsForField(field));
500 }
501 
Field_getSignatureAnnotation(JNIEnv * env,jobject javaField)502 static jobjectArray Field_getSignatureAnnotation(JNIEnv* env, jobject javaField) {
503   ScopedFastNativeObjectAccess soa(env);
504   ArtField* field = soa.Decode<mirror::Field>(javaField)->GetArtField();
505   if (field->GetDeclaringClass()->IsProxyClass()) {
506     return nullptr;
507   }
508   return soa.AddLocalReference<jobjectArray>(annotations::GetSignatureAnnotationForField(field));
509 }
510 
Field_isAnnotationPresentNative(JNIEnv * env,jobject javaField,jclass annotationType)511 static jboolean Field_isAnnotationPresentNative(JNIEnv* env,
512                                                 jobject javaField,
513                                                 jclass annotationType) {
514   ScopedFastNativeObjectAccess soa(env);
515   StackHandleScope<1> hs(soa.Self());
516   ArtField* field = soa.Decode<mirror::Field>(javaField)->GetArtField();
517   if (field->GetDeclaringClass()->IsProxyClass()) {
518     return false;
519   }
520   Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class>(annotationType)));
521   return annotations::IsFieldAnnotationPresent(field, klass);
522 }
523 
524 static JNINativeMethod gMethods[] = {
525   FAST_NATIVE_METHOD(Field, get,        "(Ljava/lang/Object;)Ljava/lang/Object;"),
526   FAST_NATIVE_METHOD(Field, getBoolean, "(Ljava/lang/Object;)Z"),
527   FAST_NATIVE_METHOD(Field, getByte,    "(Ljava/lang/Object;)B"),
528   FAST_NATIVE_METHOD(Field, getChar,    "(Ljava/lang/Object;)C"),
529   FAST_NATIVE_METHOD(Field, getAnnotationNative,
530                 "(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;"),
531   FAST_NATIVE_METHOD(Field, getArtField, "()J"),
532   FAST_NATIVE_METHOD(Field, getDeclaredAnnotations, "()[Ljava/lang/annotation/Annotation;"),
533   FAST_NATIVE_METHOD(Field, getSignatureAnnotation, "()[Ljava/lang/String;"),
534   FAST_NATIVE_METHOD(Field, getDouble,  "(Ljava/lang/Object;)D"),
535   FAST_NATIVE_METHOD(Field, getFloat,   "(Ljava/lang/Object;)F"),
536   FAST_NATIVE_METHOD(Field, getInt,     "(Ljava/lang/Object;)I"),
537   FAST_NATIVE_METHOD(Field, getLong,    "(Ljava/lang/Object;)J"),
538   FAST_NATIVE_METHOD(Field, getNameInternal, "()Ljava/lang/String;"),
539   FAST_NATIVE_METHOD(Field, getShort,   "(Ljava/lang/Object;)S"),
540   FAST_NATIVE_METHOD(Field, isAnnotationPresentNative, "(Ljava/lang/Class;)Z"),
541   FAST_NATIVE_METHOD(Field, set,        "(Ljava/lang/Object;Ljava/lang/Object;)V"),
542   FAST_NATIVE_METHOD(Field, setBoolean, "(Ljava/lang/Object;Z)V"),
543   FAST_NATIVE_METHOD(Field, setByte,    "(Ljava/lang/Object;B)V"),
544   FAST_NATIVE_METHOD(Field, setChar,    "(Ljava/lang/Object;C)V"),
545   FAST_NATIVE_METHOD(Field, setDouble,  "(Ljava/lang/Object;D)V"),
546   FAST_NATIVE_METHOD(Field, setFloat,   "(Ljava/lang/Object;F)V"),
547   FAST_NATIVE_METHOD(Field, setInt,     "(Ljava/lang/Object;I)V"),
548   FAST_NATIVE_METHOD(Field, setLong,    "(Ljava/lang/Object;J)V"),
549   FAST_NATIVE_METHOD(Field, setShort,   "(Ljava/lang/Object;S)V"),
550 };
551 
register_java_lang_reflect_Field(JNIEnv * env)552 void register_java_lang_reflect_Field(JNIEnv* env) {
553   REGISTER_NATIVE_METHODS("java/lang/reflect/Field");
554 }
555 
556 }  // namespace art
557