xref: /aosp_15_r20/art/runtime/native/java_lang_reflect_Field.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
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 HIDDEN {
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 
ThrowIAEIfRecordFinalField(ObjPtr<mirror::Field> field)343 ALWAYS_INLINE inline static bool ThrowIAEIfRecordFinalField(ObjPtr<mirror::Field> field)
344     REQUIRES_SHARED(Locks::mutator_lock_) {
345   if (!(field->IsFinal())) {
346     return false;
347   }
348   ObjPtr<mirror::Class> declaring_class = field->GetDeclaringClass();
349   DCHECK(declaring_class != nullptr);
350   if (!(declaring_class->IsRecordClass())) {
351     return false;
352   }
353 
354   ThrowIllegalAccessException(
355           StringPrintf("Cannot set %s field %s of record class %s",
356               PrettyJavaAccessFlags(field->GetAccessFlags()).c_str(),
357               ArtField::PrettyField(field->GetArtField()).c_str(),
358               declaring_class->PrettyClass().c_str()).c_str());
359 
360   return true;
361 }
362 
Field_set(JNIEnv * env,jobject javaField,jobject javaObj,jobject javaValue)363 static void Field_set(JNIEnv* env, jobject javaField, jobject javaObj, jobject javaValue) {
364   ScopedFastNativeObjectAccess soa(env);
365   ObjPtr<mirror::Field> f = soa.Decode<mirror::Field>(javaField);
366   // Check that the receiver is non-null and an instance of the field's declaring class.
367   ObjPtr<mirror::Object> o;
368   if (!CheckReceiver(soa, javaObj, &f, &o)) {
369     DCHECK(soa.Self()->IsExceptionPending());
370     return;
371   }
372   if (ThrowIAEIfRecordFinalField(f)) {
373     DCHECK(soa.Self()->IsExceptionPending());
374     return;
375   }
376   ObjPtr<mirror::Class> field_type;
377   const char* field_type_descriptor = f->GetArtField()->GetTypeDescriptor();
378   Primitive::Type field_prim_type = Primitive::GetType(field_type_descriptor[0]);
379   if (field_prim_type == Primitive::kPrimNot) {
380     field_type = f->GetType();
381   } else {
382     field_type =
383         Runtime::Current()->GetClassLinker()->LookupPrimitiveClass(field_type_descriptor[0]);
384   }
385   DCHECK(field_type != nullptr) << field_type_descriptor;
386   // We now don't expect suspension unless an exception is thrown.
387   // Unbox the value, if necessary.
388   ObjPtr<mirror::Object> boxed_value = soa.Decode<mirror::Object>(javaValue);
389   JValue unboxed_value;
390   if (!UnboxPrimitiveForField(boxed_value,
391                               field_type,
392                               f->GetArtField(),
393                               &unboxed_value)) {
394     DCHECK(soa.Self()->IsExceptionPending());
395     return;
396   }
397   // If field is not set to be accessible, verify it can be accessed by the caller.
398   if (!f->IsAccessible() && !VerifyFieldAccess<true>(soa.Self(), f, o)) {
399     DCHECK(soa.Self()->IsExceptionPending());
400     return;
401   }
402   SetFieldValue(o, f, field_prim_type, true, unboxed_value);
403 }
404 
405 template<Primitive::Type kPrimitiveType>
SetPrimitiveField(JNIEnv * env,jobject javaField,jobject javaObj,const JValue & new_value)406 static void SetPrimitiveField(JNIEnv* env,
407                               jobject javaField,
408                               jobject javaObj,
409                               const JValue& new_value) {
410   ScopedFastNativeObjectAccess soa(env);
411   ObjPtr<mirror::Field> f = soa.Decode<mirror::Field>(javaField);
412   ObjPtr<mirror::Object> o;
413   if (!CheckReceiver(soa, javaObj, &f, &o)) {
414     return;
415   }
416   if (ThrowIAEIfRecordFinalField(f)) {
417     DCHECK(soa.Self()->IsExceptionPending());
418     return;
419   }
420   Primitive::Type field_type = f->GetTypeAsPrimitiveType();
421   if (UNLIKELY(field_type == Primitive::kPrimNot)) {
422     ThrowIllegalArgumentException(
423         StringPrintf("Not a primitive field: %s",
424                      ArtField::PrettyField(f->GetArtField()).c_str()).c_str());
425     return;
426   }
427 
428   // Widen the value if necessary (and possible).
429   JValue wide_value;
430   if (!ConvertPrimitiveValue(false, kPrimitiveType, field_type, new_value, &wide_value)) {
431     DCHECK(soa.Self()->IsExceptionPending());
432     return;
433   }
434 
435   // If field is not set to be accessible, verify it can be accessed by the caller.
436   if (!f->IsAccessible() && !VerifyFieldAccess<true>(soa.Self(), f, o)) {
437     DCHECK(soa.Self()->IsExceptionPending());
438     return;
439   }
440 
441   // Write the value.
442   SetFieldValue(o, f, field_type, false, wide_value);
443 }
444 
Field_setBoolean(JNIEnv * env,jobject javaField,jobject javaObj,jboolean z)445 static void Field_setBoolean(JNIEnv* env, jobject javaField, jobject javaObj, jboolean z) {
446   JValue value;
447   value.SetZ(z);
448   SetPrimitiveField<Primitive::kPrimBoolean>(env, javaField, javaObj, value);
449 }
450 
Field_setByte(JNIEnv * env,jobject javaField,jobject javaObj,jbyte b)451 static void Field_setByte(JNIEnv* env, jobject javaField, jobject javaObj, jbyte b) {
452   JValue value;
453   value.SetB(b);
454   SetPrimitiveField<Primitive::kPrimByte>(env, javaField, javaObj, value);
455 }
456 
Field_setChar(JNIEnv * env,jobject javaField,jobject javaObj,jchar c)457 static void Field_setChar(JNIEnv* env, jobject javaField, jobject javaObj, jchar c) {
458   JValue value;
459   value.SetC(c);
460   SetPrimitiveField<Primitive::kPrimChar>(env, javaField, javaObj, value);
461 }
462 
Field_setDouble(JNIEnv * env,jobject javaField,jobject javaObj,jdouble d)463 static void Field_setDouble(JNIEnv* env, jobject javaField, jobject javaObj, jdouble d) {
464   JValue value;
465   value.SetD(d);
466   SetPrimitiveField<Primitive::kPrimDouble>(env, javaField, javaObj, value);
467 }
468 
Field_setFloat(JNIEnv * env,jobject javaField,jobject javaObj,jfloat f)469 static void Field_setFloat(JNIEnv* env, jobject javaField, jobject javaObj, jfloat f) {
470   JValue value;
471   value.SetF(f);
472   SetPrimitiveField<Primitive::kPrimFloat>(env, javaField, javaObj, value);
473 }
474 
Field_setInt(JNIEnv * env,jobject javaField,jobject javaObj,jint i)475 static void Field_setInt(JNIEnv* env, jobject javaField, jobject javaObj, jint i) {
476   JValue value;
477   value.SetI(i);
478   SetPrimitiveField<Primitive::kPrimInt>(env, javaField, javaObj, value);
479 }
480 
Field_setLong(JNIEnv * env,jobject javaField,jobject javaObj,jlong j)481 static void Field_setLong(JNIEnv* env, jobject javaField, jobject javaObj, jlong j) {
482   JValue value;
483   value.SetJ(j);
484   SetPrimitiveField<Primitive::kPrimLong>(env, javaField, javaObj, value);
485 }
486 
Field_setShort(JNIEnv * env,jobject javaField,jobject javaObj,jshort s)487 static void Field_setShort(JNIEnv* env, jobject javaField, jobject javaObj, jshort s) {
488   JValue value;
489   value.SetS(s);
490   SetPrimitiveField<Primitive::kPrimShort>(env, javaField, javaObj, value);
491 }
492 
Field_getAnnotationNative(JNIEnv * env,jobject javaField,jclass annotationType)493 static jobject Field_getAnnotationNative(JNIEnv* env, jobject javaField, jclass annotationType) {
494   ScopedFastNativeObjectAccess soa(env);
495   StackHandleScope<1> hs(soa.Self());
496   ArtField* field = soa.Decode<mirror::Field>(javaField)->GetArtField();
497   if (field->GetDeclaringClass()->IsProxyClass()) {
498     return nullptr;
499   }
500   Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class>(annotationType)));
501   return soa.AddLocalReference<jobject>(annotations::GetAnnotationForField(field, klass));
502 }
503 
Field_getArtField(JNIEnv * env,jobject javaField)504 static jlong Field_getArtField(JNIEnv* env, jobject javaField) {
505   ScopedFastNativeObjectAccess soa(env);
506   ArtField* field = soa.Decode<mirror::Field>(javaField)->GetArtField();
507   return reinterpret_cast<jlong>(field);
508 }
509 
Field_getNameInternal(JNIEnv * env,jobject javaField)510 static jstring Field_getNameInternal(JNIEnv* env, jobject javaField) {
511   ScopedFastNativeObjectAccess soa(env);
512   ArtField* field = soa.Decode<mirror::Field>(javaField)->GetArtField();
513   return soa.AddLocalReference<jstring>(field->ResolveNameString());
514 }
515 
Field_getDeclaredAnnotations(JNIEnv * env,jobject javaField)516 static jobjectArray Field_getDeclaredAnnotations(JNIEnv* env, jobject javaField) {
517   ScopedFastNativeObjectAccess soa(env);
518   ArtField* field = soa.Decode<mirror::Field>(javaField)->GetArtField();
519   if (field->GetDeclaringClass()->IsProxyClass()) {
520     // Return an empty array instead of a null pointer.
521     ObjPtr<mirror::Class> annotation_array_class =
522         WellKnownClasses::ToClass(WellKnownClasses::java_lang_annotation_Annotation__array);
523     ObjPtr<mirror::ObjectArray<mirror::Object>> empty_array =
524         mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), annotation_array_class, 0);
525     return soa.AddLocalReference<jobjectArray>(empty_array);
526   }
527   return soa.AddLocalReference<jobjectArray>(annotations::GetAnnotationsForField(field));
528 }
529 
Field_getSignatureAnnotation(JNIEnv * env,jobject javaField)530 static jobjectArray Field_getSignatureAnnotation(JNIEnv* env, jobject javaField) {
531   ScopedFastNativeObjectAccess soa(env);
532   ArtField* field = soa.Decode<mirror::Field>(javaField)->GetArtField();
533   if (field->GetDeclaringClass()->IsProxyClass()) {
534     return nullptr;
535   }
536   return soa.AddLocalReference<jobjectArray>(annotations::GetSignatureAnnotationForField(field));
537 }
538 
Field_isAnnotationPresentNative(JNIEnv * env,jobject javaField,jclass annotationType)539 static jboolean Field_isAnnotationPresentNative(JNIEnv* env,
540                                                 jobject javaField,
541                                                 jclass annotationType) {
542   ScopedFastNativeObjectAccess soa(env);
543   StackHandleScope<1> hs(soa.Self());
544   ArtField* field = soa.Decode<mirror::Field>(javaField)->GetArtField();
545   if (field->GetDeclaringClass()->IsProxyClass()) {
546     return false;
547   }
548   Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class>(annotationType)));
549   return annotations::IsFieldAnnotationPresent(field, klass);
550 }
551 
552 static JNINativeMethod gMethods[] = {
553   FAST_NATIVE_METHOD(Field, get,        "(Ljava/lang/Object;)Ljava/lang/Object;"),
554   FAST_NATIVE_METHOD(Field, getBoolean, "(Ljava/lang/Object;)Z"),
555   FAST_NATIVE_METHOD(Field, getByte,    "(Ljava/lang/Object;)B"),
556   FAST_NATIVE_METHOD(Field, getChar,    "(Ljava/lang/Object;)C"),
557   FAST_NATIVE_METHOD(Field, getAnnotationNative,
558                 "(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;"),
559   FAST_NATIVE_METHOD(Field, getArtField, "()J"),
560   FAST_NATIVE_METHOD(Field, getDeclaredAnnotations, "()[Ljava/lang/annotation/Annotation;"),
561   FAST_NATIVE_METHOD(Field, getSignatureAnnotation, "()[Ljava/lang/String;"),
562   FAST_NATIVE_METHOD(Field, getDouble,  "(Ljava/lang/Object;)D"),
563   FAST_NATIVE_METHOD(Field, getFloat,   "(Ljava/lang/Object;)F"),
564   FAST_NATIVE_METHOD(Field, getInt,     "(Ljava/lang/Object;)I"),
565   FAST_NATIVE_METHOD(Field, getLong,    "(Ljava/lang/Object;)J"),
566   FAST_NATIVE_METHOD(Field, getNameInternal, "()Ljava/lang/String;"),
567   FAST_NATIVE_METHOD(Field, getShort,   "(Ljava/lang/Object;)S"),
568   FAST_NATIVE_METHOD(Field, isAnnotationPresentNative, "(Ljava/lang/Class;)Z"),
569   FAST_NATIVE_METHOD(Field, set,        "(Ljava/lang/Object;Ljava/lang/Object;)V"),
570   FAST_NATIVE_METHOD(Field, setBoolean, "(Ljava/lang/Object;Z)V"),
571   FAST_NATIVE_METHOD(Field, setByte,    "(Ljava/lang/Object;B)V"),
572   FAST_NATIVE_METHOD(Field, setChar,    "(Ljava/lang/Object;C)V"),
573   FAST_NATIVE_METHOD(Field, setDouble,  "(Ljava/lang/Object;D)V"),
574   FAST_NATIVE_METHOD(Field, setFloat,   "(Ljava/lang/Object;F)V"),
575   FAST_NATIVE_METHOD(Field, setInt,     "(Ljava/lang/Object;I)V"),
576   FAST_NATIVE_METHOD(Field, setLong,    "(Ljava/lang/Object;J)V"),
577   FAST_NATIVE_METHOD(Field, setShort,   "(Ljava/lang/Object;S)V"),
578 };
579 
register_java_lang_reflect_Field(JNIEnv * env)580 void register_java_lang_reflect_Field(JNIEnv* env) {
581   REGISTER_NATIVE_METHODS("java/lang/reflect/Field");
582 }
583 
584 }  // namespace art
585