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