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