blob: dab510dc8c3afd37587b93b8399d235adea2c848 [file] [log] [blame]
Brian Carlstromf867b6f2011-09-16 12:17:25 -07001/*
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
Andreas Gampe277ccbd2014-11-03 21:36:10 -080017#include "java_lang_reflect_Field.h"
18
Brian Carlstromf867b6f2011-09-16 12:17:25 -070019#include "class_linker.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080020#include "class_linker-inl.h"
Ian Rogers62d6c772013-02-27 08:32:07 -080021#include "common_throws.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070022#include "dex_file-inl.h"
David Sehr9323e6e2016-09-13 08:58:35 -070023#include "dex_file_annotations.h"
Elliott Hugheseac76672012-05-24 21:56:51 -070024#include "jni_internal.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070025#include "mirror/class-inl.h"
Mathieu Chartierdaaf3262015-03-24 13:30:28 -070026#include "mirror/field.h"
Mathieu Chartier76433272014-09-26 14:32:37 -070027#include "reflection-inl.h"
Ian Rogers1eb512d2013-10-18 15:42:20 -070028#include "scoped_fast_native_object_access.h"
Vladimir Marko80afd022015-05-19 18:08:00 +010029#include "utils.h"
Brian Carlstromf867b6f2011-09-16 12:17:25 -070030
Brian Carlstromf867b6f2011-09-16 12:17:25 -070031namespace art {
32
Mathieu Chartier76433272014-09-26 14:32:37 -070033template<bool kIsSet>
Mathieu Chartierdaaf3262015-03-24 13:30:28 -070034ALWAYS_INLINE inline static bool VerifyFieldAccess(Thread* self, mirror::Field* field,
Mathieu Chartier76433272014-09-26 14:32:37 -070035 mirror::Object* obj)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070036 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier76433272014-09-26 14:32:37 -070037 if (kIsSet && field->IsFinal()) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +000038 ThrowIllegalAccessException(
Andreas Gampec0d82292014-09-23 10:38:30 -070039 StringPrintf("Cannot set %s field %s of class %s",
40 PrettyJavaAccessFlags(field->GetAccessFlags()).c_str(),
Mathieu Chartierdaaf3262015-03-24 13:30:28 -070041 PrettyField(field->GetArtField()).c_str(),
Andreas Gampec0d82292014-09-23 10:38:30 -070042 field->GetDeclaringClass() == nullptr ? "null" :
43 PrettyClass(field->GetDeclaringClass()).c_str()).c_str());
Jeff Hao11d5d8f2014-03-26 15:08:20 -070044 return false;
45 }
Mathieu Chartiera59d9b22016-09-26 18:13:17 -070046 ObjPtr<mirror::Class> calling_class;
47 if (!VerifyAccess(self,
48 MakeObjPtr(obj),
49 MakeObjPtr(field->GetDeclaringClass()),
50 field->GetAccessFlags(),
51 &calling_class,
52 1)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +000053 ThrowIllegalAccessException(
Andreas Gampec0d82292014-09-23 10:38:30 -070054 StringPrintf("Class %s cannot access %s field %s of class %s",
55 calling_class == nullptr ? "null" : PrettyClass(calling_class).c_str(),
56 PrettyJavaAccessFlags(field->GetAccessFlags()).c_str(),
Mathieu Chartierdaaf3262015-03-24 13:30:28 -070057 PrettyField(field->GetArtField()).c_str(),
Andreas Gampec0d82292014-09-23 10:38:30 -070058 field->GetDeclaringClass() == nullptr ? "null" :
59 PrettyClass(field->GetDeclaringClass()).c_str()).c_str());
Jeff Hao11d5d8f2014-03-26 15:08:20 -070060 return false;
61 }
62 return true;
63}
64
Mathieu Chartier76433272014-09-26 14:32:37 -070065template<bool kAllowReferences>
Mathieu Chartierdaaf3262015-03-24 13:30:28 -070066ALWAYS_INLINE inline static bool GetFieldValue(mirror::Object* o, mirror::Field* f,
Ian Rogers6a3c1fc2014-10-31 00:33:20 -070067 Primitive::Type field_type, JValue* value)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070068 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogers62f05122014-03-21 11:21:29 -070069 DCHECK_EQ(value->GetJ(), INT64_C(0));
Mathieu Chartierdaaf3262015-03-24 13:30:28 -070070 MemberOffset offset(f->GetOffset());
71 const bool is_volatile = f->IsVolatile();
Ian Rogers62f05122014-03-21 11:21:29 -070072 switch (field_type) {
73 case Primitive::kPrimBoolean:
Mathieu Chartierdaaf3262015-03-24 13:30:28 -070074 value->SetZ(is_volatile ? o->GetFieldBooleanVolatile(offset) : o->GetFieldBoolean(offset));
Elliott Hughes33203b52011-09-20 19:42:01 -070075 return true;
Ian Rogers62f05122014-03-21 11:21:29 -070076 case Primitive::kPrimByte:
Mathieu Chartierdaaf3262015-03-24 13:30:28 -070077 value->SetB(is_volatile ? o->GetFieldByteVolatile(offset) : o->GetFieldByte(offset));
Ian Rogers62f05122014-03-21 11:21:29 -070078 return true;
79 case Primitive::kPrimChar:
Mathieu Chartierdaaf3262015-03-24 13:30:28 -070080 value->SetC(is_volatile ? o->GetFieldCharVolatile(offset) : o->GetFieldChar(offset));
Ian Rogers62f05122014-03-21 11:21:29 -070081 return true;
82 case Primitive::kPrimInt:
Mathieu Chartierdaaf3262015-03-24 13:30:28 -070083 case Primitive::kPrimFloat:
84 value->SetI(is_volatile ? o->GetField32Volatile(offset) : o->GetField32(offset));
Ian Rogers62f05122014-03-21 11:21:29 -070085 return true;
86 case Primitive::kPrimLong:
Mathieu Chartierdaaf3262015-03-24 13:30:28 -070087 case Primitive::kPrimDouble:
88 value->SetJ(is_volatile ? o->GetField64Volatile(offset) : o->GetField64(offset));
Ian Rogers62f05122014-03-21 11:21:29 -070089 return true;
90 case Primitive::kPrimShort:
Mathieu Chartierdaaf3262015-03-24 13:30:28 -070091 value->SetS(is_volatile ? o->GetFieldShortVolatile(offset) : o->GetFieldShort(offset));
Ian Rogers62f05122014-03-21 11:21:29 -070092 return true;
93 case Primitive::kPrimNot:
Mathieu Chartier76433272014-09-26 14:32:37 -070094 if (kAllowReferences) {
Mathieu Chartierdaaf3262015-03-24 13:30:28 -070095 value->SetL(is_volatile ? o->GetFieldObjectVolatile<mirror::Object>(offset) :
96 o->GetFieldObject<mirror::Object>(offset));
Ian Rogers62f05122014-03-21 11:21:29 -070097 return true;
98 }
99 // Else break to report an error.
100 break;
101 case Primitive::kPrimVoid:
102 // Never okay.
103 break;
Elliott Hughes33203b52011-09-20 19:42:01 -0700104 }
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700105 ThrowIllegalArgumentException(
106 StringPrintf("Not a primitive field: %s", PrettyField(f->GetArtField()).c_str()).c_str());
Elliott Hughes33203b52011-09-20 19:42:01 -0700107 return false;
108}
109
Mathieu Chartier76433272014-09-26 14:32:37 -0700110ALWAYS_INLINE inline static bool CheckReceiver(const ScopedFastNativeObjectAccess& soa,
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700111 jobject j_rcvr, mirror::Field** f,
Mathieu Chartier76433272014-09-26 14:32:37 -0700112 mirror::Object** class_or_rcvr)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700113 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogers62f05122014-03-21 11:21:29 -0700114 soa.Self()->AssertThreadSuspensionIsAllowable();
Mathieu Chartier76433272014-09-26 14:32:37 -0700115 mirror::Class* declaringClass = (*f)->GetDeclaringClass();
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700116 if ((*f)->IsStatic()) {
Mathieu Chartier76433272014-09-26 14:32:37 -0700117 if (UNLIKELY(!declaringClass->IsInitialized())) {
Mathieu Chartier76433272014-09-26 14:32:37 -0700118 StackHandleScope<2> hs(soa.Self());
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700119 HandleWrapper<mirror::Field> h_f(hs.NewHandleWrapper(f));
Mathieu Chartier76433272014-09-26 14:32:37 -0700120 HandleWrapper<mirror::Class> h_klass(hs.NewHandleWrapper(&declaringClass));
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700121 ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
Mathieu Chartier76433272014-09-26 14:32:37 -0700122 if (UNLIKELY(!class_linker->EnsureInitialized(soa.Self(), h_klass, true, true))) {
123 DCHECK(soa.Self()->IsExceptionPending());
124 return false;
125 }
Ian Rogers62f05122014-03-21 11:21:29 -0700126 }
Mathieu Chartier76433272014-09-26 14:32:37 -0700127 *class_or_rcvr = declaringClass;
Elliott Hughesed1c1e32011-10-02 14:31:05 -0700128 return true;
129 }
Ian Rogers62f05122014-03-21 11:21:29 -0700130 *class_or_rcvr = soa.Decode<mirror::Object*>(j_rcvr);
Mathieu Chartiera59d9b22016-09-26 18:13:17 -0700131 if (!VerifyObjectIsClass(MakeObjPtr(*class_or_rcvr), MakeObjPtr(declaringClass))) {
Ian Rogers62f05122014-03-21 11:21:29 -0700132 DCHECK(soa.Self()->IsExceptionPending());
Elliott Hughesed1c1e32011-10-02 14:31:05 -0700133 return false;
134 }
135 return true;
136}
137
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700138static jobject Field_get(JNIEnv* env, jobject javaField, jobject javaObj) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700139 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700140 mirror::Field* f = soa.Decode<mirror::Field*>(javaField);
Ian Rogers62f05122014-03-21 11:21:29 -0700141 mirror::Object* o = nullptr;
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700142 if (!CheckReceiver(soa, javaObj, &f, &o)) {
Ian Rogers62f05122014-03-21 11:21:29 -0700143 DCHECK(soa.Self()->IsExceptionPending());
144 return nullptr;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800145 }
Jeff Haocb4581a2014-03-28 15:43:37 -0700146 // If field is not set to be accessible, verify it can be accessed by the caller.
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700147 if (!f->IsAccessible() && !VerifyFieldAccess<false>(soa.Self(), f, o)) {
Jeff Hao11d5d8f2014-03-26 15:08:20 -0700148 DCHECK(soa.Self()->IsExceptionPending());
149 return nullptr;
150 }
Ian Rogers62f05122014-03-21 11:21:29 -0700151 // We now don't expect suspension unless an exception is thrown.
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800152 // Get the field's value, boxing if necessary.
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700153 Primitive::Type field_type = f->GetTypeAsPrimitiveType();
Elliott Hughes1d878f32012-04-11 15:17:54 -0700154 JValue value;
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700155 if (!GetFieldValue<true>(o, f, field_type, &value)) {
Ian Rogers62f05122014-03-21 11:21:29 -0700156 DCHECK(soa.Self()->IsExceptionPending());
157 return nullptr;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800158 }
Mathieu Chartiera59d9b22016-09-26 18:13:17 -0700159 return soa.AddLocalReference<jobject>(BoxPrimitive(field_type, value).Decode());
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800160}
161
Mathieu Chartier76433272014-09-26 14:32:37 -0700162template<Primitive::Type kPrimitiveType>
163ALWAYS_INLINE inline static JValue GetPrimitiveField(JNIEnv* env, jobject javaField,
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700164 jobject javaObj) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700165 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700166 mirror::Field* f = soa.Decode<mirror::Field*>(javaField);
Ian Rogers62f05122014-03-21 11:21:29 -0700167 mirror::Object* o = nullptr;
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700168 if (!CheckReceiver(soa, javaObj, &f, &o)) {
Ian Rogers62f05122014-03-21 11:21:29 -0700169 DCHECK(soa.Self()->IsExceptionPending());
Elliott Hughesed1c1e32011-10-02 14:31:05 -0700170 return JValue();
Elliott Hughes33203b52011-09-20 19:42:01 -0700171 }
Jeff Hao11d5d8f2014-03-26 15:08:20 -0700172
Jeff Haocb4581a2014-03-28 15:43:37 -0700173 // If field is not set to be accessible, verify it can be accessed by the caller.
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700174 if (!f->IsAccessible() && !VerifyFieldAccess<false>(soa.Self(), f, o)) {
Jeff Hao11d5d8f2014-03-26 15:08:20 -0700175 DCHECK(soa.Self()->IsExceptionPending());
176 return JValue();
177 }
178
Ian Rogers62f05122014-03-21 11:21:29 -0700179 // We now don't expect suspension unless an exception is thrown.
Elliott Hughes33203b52011-09-20 19:42:01 -0700180 // Read the value.
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700181 Primitive::Type field_type = f->GetTypeAsPrimitiveType();
Elliott Hughes1d878f32012-04-11 15:17:54 -0700182 JValue field_value;
Mathieu Chartier76433272014-09-26 14:32:37 -0700183 if (field_type == kPrimitiveType) {
184 // This if statement should get optimized out since we only pass in valid primitive types.
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700185 if (UNLIKELY(!GetFieldValue<false>(o, f, kPrimitiveType, &field_value))) {
Mathieu Chartier76433272014-09-26 14:32:37 -0700186 DCHECK(soa.Self()->IsExceptionPending());
187 return JValue();
188 }
189 return field_value;
190 }
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700191 if (!GetFieldValue<false>(o, f, field_type, &field_value)) {
Ian Rogers62f05122014-03-21 11:21:29 -0700192 DCHECK(soa.Self()->IsExceptionPending());
Elliott Hughes33203b52011-09-20 19:42:01 -0700193 return JValue();
194 }
Elliott Hughes33203b52011-09-20 19:42:01 -0700195 // Widen it if necessary (and possible).
196 JValue wide_value;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000197 if (!ConvertPrimitiveValue(false, field_type, kPrimitiveType, field_value,
Mathieu Chartier76433272014-09-26 14:32:37 -0700198 &wide_value)) {
Ian Rogers62f05122014-03-21 11:21:29 -0700199 DCHECK(soa.Self()->IsExceptionPending());
Elliott Hughes33203b52011-09-20 19:42:01 -0700200 return JValue();
201 }
202 return wide_value;
203}
204
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700205static jboolean Field_getBoolean(JNIEnv* env, jobject javaField, jobject javaObj) {
206 return GetPrimitiveField<Primitive::kPrimBoolean>(env, javaField, javaObj).GetZ();
Elliott Hughes33203b52011-09-20 19:42:01 -0700207}
208
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700209static jbyte Field_getByte(JNIEnv* env, jobject javaField, jobject javaObj) {
210 return GetPrimitiveField<Primitive::kPrimByte>(env, javaField, javaObj).GetB();
Elliott Hughes33203b52011-09-20 19:42:01 -0700211}
212
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700213static jchar Field_getChar(JNIEnv* env, jobject javaField, jobject javaObj) {
214 return GetPrimitiveField<Primitive::kPrimChar>(env, javaField, javaObj).GetC();
Elliott Hughes33203b52011-09-20 19:42:01 -0700215}
216
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700217static jdouble Field_getDouble(JNIEnv* env, jobject javaField, jobject javaObj) {
218 return GetPrimitiveField<Primitive::kPrimDouble>(env, javaField, javaObj).GetD();
Elliott Hughes33203b52011-09-20 19:42:01 -0700219}
220
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700221static jfloat Field_getFloat(JNIEnv* env, jobject javaField, jobject javaObj) {
222 return GetPrimitiveField<Primitive::kPrimFloat>(env, javaField, javaObj).GetF();
Elliott Hughes33203b52011-09-20 19:42:01 -0700223}
224
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700225static jint Field_getInt(JNIEnv* env, jobject javaField, jobject javaObj) {
226 return GetPrimitiveField<Primitive::kPrimInt>(env, javaField, javaObj).GetI();
Elliott Hughes33203b52011-09-20 19:42:01 -0700227}
228
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700229static jlong Field_getLong(JNIEnv* env, jobject javaField, jobject javaObj) {
230 return GetPrimitiveField<Primitive::kPrimLong>(env, javaField, javaObj).GetJ();
Elliott Hughes33203b52011-09-20 19:42:01 -0700231}
232
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700233static jshort Field_getShort(JNIEnv* env, jobject javaField, jobject javaObj) {
234 return GetPrimitiveField<Primitive::kPrimShort>(env, javaField, javaObj).GetS();
Elliott Hughes33203b52011-09-20 19:42:01 -0700235}
236
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700237ALWAYS_INLINE inline static void SetFieldValue(mirror::Object* o, mirror::Field* f,
238 Primitive::Type field_type, bool allow_references,
239 const JValue& new_value)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700240 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogers62f05122014-03-21 11:21:29 -0700241 DCHECK(f->GetDeclaringClass()->IsInitialized());
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700242 MemberOffset offset(f->GetOffset());
243 const bool is_volatile = f->IsVolatile();
Ian Rogers62f05122014-03-21 11:21:29 -0700244 switch (field_type) {
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700245 case Primitive::kPrimBoolean:
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700246 if (is_volatile) {
247 o->SetFieldBooleanVolatile<false>(offset, new_value.GetZ());
248 } else {
249 o->SetFieldBoolean<false>(offset, new_value.GetZ());
250 }
Elliott Hughesfe6207f2011-09-26 17:24:06 -0700251 break;
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700252 case Primitive::kPrimByte:
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700253 if (is_volatile) {
254 o->SetFieldBooleanVolatile<false>(offset, new_value.GetB());
255 } else {
256 o->SetFieldBoolean<false>(offset, new_value.GetB());
257 }
Elliott Hughesfe6207f2011-09-26 17:24:06 -0700258 break;
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700259 case Primitive::kPrimChar:
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700260 if (is_volatile) {
Fredrik Roubert3152c822015-07-28 00:14:08 +0200261 o->SetFieldCharVolatile<false>(offset, new_value.GetC());
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700262 } else {
Fredrik Roubert3152c822015-07-28 00:14:08 +0200263 o->SetFieldChar<false>(offset, new_value.GetC());
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700264 }
Elliott Hughesfe6207f2011-09-26 17:24:06 -0700265 break;
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700266 case Primitive::kPrimInt:
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700267 case Primitive::kPrimFloat:
268 if (is_volatile) {
269 o->SetField32Volatile<false>(offset, new_value.GetI());
270 } else {
271 o->SetField32<false>(offset, new_value.GetI());
272 }
Elliott Hughesfe6207f2011-09-26 17:24:06 -0700273 break;
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700274 case Primitive::kPrimLong:
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700275 case Primitive::kPrimDouble:
276 if (is_volatile) {
277 o->SetField64Volatile<false>(offset, new_value.GetJ());
278 } else {
279 o->SetField64<false>(offset, new_value.GetJ());
280 }
Elliott Hughesfe6207f2011-09-26 17:24:06 -0700281 break;
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700282 case Primitive::kPrimShort:
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700283 if (is_volatile) {
Mathieu Chartierca239af2015-03-29 18:27:50 -0700284 o->SetFieldShortVolatile<false>(offset, new_value.GetS());
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700285 } else {
Mathieu Chartierca239af2015-03-29 18:27:50 -0700286 o->SetFieldShort<false>(offset, new_value.GetS());
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700287 }
Elliott Hughesfe6207f2011-09-26 17:24:06 -0700288 break;
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700289 case Primitive::kPrimNot:
Elliott Hughes33203b52011-09-20 19:42:01 -0700290 if (allow_references) {
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700291 if (is_volatile) {
292 o->SetFieldObjectVolatile<false>(offset, new_value.GetL());
293 } else {
294 o->SetFieldObject<false>(offset, new_value.GetL());
295 }
Elliott Hughesfe6207f2011-09-26 17:24:06 -0700296 break;
Elliott Hughes33203b52011-09-20 19:42:01 -0700297 }
Elliott Hughesfe6207f2011-09-26 17:24:06 -0700298 // Else fall through to report an error.
Ian Rogersfc787ec2014-10-09 21:56:44 -0700299 FALLTHROUGH_INTENDED;
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700300 case Primitive::kPrimVoid:
Elliott Hughes33203b52011-09-20 19:42:01 -0700301 // Never okay.
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000302 ThrowIllegalArgumentException(StringPrintf("Not a primitive field: %s",
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700303 PrettyField(f->GetArtField()).c_str()).c_str());
Elliott Hughesfe6207f2011-09-26 17:24:06 -0700304 return;
Elliott Hughes33203b52011-09-20 19:42:01 -0700305 }
Elliott Hughes33203b52011-09-20 19:42:01 -0700306}
307
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700308static void Field_set(JNIEnv* env, jobject javaField, jobject javaObj, jobject javaValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700309 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700310 mirror::Field* f = soa.Decode<mirror::Field*>(javaField);
Ian Rogers62f05122014-03-21 11:21:29 -0700311 // Check that the receiver is non-null and an instance of the field's declaring class.
312 mirror::Object* o = nullptr;
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700313 if (!CheckReceiver(soa, javaObj, &f, &o)) {
Ian Rogers62f05122014-03-21 11:21:29 -0700314 DCHECK(soa.Self()->IsExceptionPending());
315 return;
316 }
Ian Rogers62f05122014-03-21 11:21:29 -0700317 mirror::Class* field_type;
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700318 const char* field_type_desciptor = f->GetArtField()->GetTypeDescriptor();
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700319 Primitive::Type field_prim_type = Primitive::GetType(field_type_desciptor[0]);
320 if (field_prim_type == Primitive::kPrimNot) {
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700321 field_type = f->GetType();
322 DCHECK(field_type != nullptr);
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700323 } else {
324 field_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(field_type_desciptor[0]);
Ian Rogers62f05122014-03-21 11:21:29 -0700325 }
326 // We now don't expect suspension unless an exception is thrown.
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800327 // Unbox the value, if necessary.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800328 mirror::Object* boxed_value = soa.Decode<mirror::Object*>(javaValue);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800329 JValue unboxed_value;
Mathieu Chartiera59d9b22016-09-26 18:13:17 -0700330 if (!UnboxPrimitiveForField(MakeObjPtr(boxed_value),
331 MakeObjPtr(field_type),
332 f->GetArtField(),
333 &unboxed_value)) {
Ian Rogers62f05122014-03-21 11:21:29 -0700334 DCHECK(soa.Self()->IsExceptionPending());
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800335 return;
336 }
Jeff Haocb4581a2014-03-28 15:43:37 -0700337 // If field is not set to be accessible, verify it can be accessed by the caller.
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700338 if (!f->IsAccessible() && !VerifyFieldAccess<true>(soa.Self(), f, o)) {
Jeff Hao11d5d8f2014-03-26 15:08:20 -0700339 DCHECK(soa.Self()->IsExceptionPending());
340 return;
341 }
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700342 SetFieldValue(o, f, field_prim_type, true, unboxed_value);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800343}
344
Mathieu Chartier76433272014-09-26 14:32:37 -0700345template<Primitive::Type kPrimitiveType>
346static void SetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj,
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700347 const JValue& new_value) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700348 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700349 mirror::Field* f = soa.Decode<mirror::Field*>(javaField);
Ian Rogers62f05122014-03-21 11:21:29 -0700350 mirror::Object* o = nullptr;
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700351 if (!CheckReceiver(soa, javaObj, &f, &o)) {
Elliott Hughesed1c1e32011-10-02 14:31:05 -0700352 return;
Elliott Hughes33203b52011-09-20 19:42:01 -0700353 }
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700354 Primitive::Type field_type = f->GetTypeAsPrimitiveType();
Ian Rogers62f05122014-03-21 11:21:29 -0700355 if (UNLIKELY(field_type == Primitive::kPrimNot)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000356 ThrowIllegalArgumentException(StringPrintf("Not a primitive field: %s",
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700357 PrettyField(f->GetArtField()).c_str()).c_str());
Jesse Wilsonc129a6b2011-11-24 14:47:46 -0500358 return;
359 }
Elliott Hughes33203b52011-09-20 19:42:01 -0700360
361 // Widen the value if necessary (and possible).
362 JValue wide_value;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000363 if (!ConvertPrimitiveValue(false, kPrimitiveType, field_type, new_value, &wide_value)) {
Ian Rogers62f05122014-03-21 11:21:29 -0700364 DCHECK(soa.Self()->IsExceptionPending());
Elliott Hughes33203b52011-09-20 19:42:01 -0700365 return;
366 }
367
Jeff Haocb4581a2014-03-28 15:43:37 -0700368 // If field is not set to be accessible, verify it can be accessed by the caller.
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700369 if (!f->IsAccessible() && !VerifyFieldAccess<true>(soa.Self(), f, o)) {
Jeff Hao11d5d8f2014-03-26 15:08:20 -0700370 DCHECK(soa.Self()->IsExceptionPending());
371 return;
372 }
373
Elliott Hughes33203b52011-09-20 19:42:01 -0700374 // Write the value.
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700375 SetFieldValue(o, f, field_type, false, wide_value);
Elliott Hughes33203b52011-09-20 19:42:01 -0700376}
377
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700378static void Field_setBoolean(JNIEnv* env, jobject javaField, jobject javaObj, jboolean z) {
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700379 JValue value;
380 value.SetZ(z);
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700381 SetPrimitiveField<Primitive::kPrimBoolean>(env, javaField, javaObj, value);
Elliott Hughes33203b52011-09-20 19:42:01 -0700382}
383
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700384static void Field_setByte(JNIEnv* env, jobject javaField, jobject javaObj, jbyte b) {
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700385 JValue value;
386 value.SetB(b);
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700387 SetPrimitiveField<Primitive::kPrimByte>(env, javaField, javaObj, value);
Elliott Hughes33203b52011-09-20 19:42:01 -0700388}
389
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700390static void Field_setChar(JNIEnv* env, jobject javaField, jobject javaObj, jchar c) {
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700391 JValue value;
392 value.SetC(c);
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700393 SetPrimitiveField<Primitive::kPrimChar>(env, javaField, javaObj, value);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800394}
Elliott Hughes33203b52011-09-20 19:42:01 -0700395
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700396static void Field_setDouble(JNIEnv* env, jobject javaField, jobject javaObj, jdouble d) {
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700397 JValue value;
398 value.SetD(d);
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700399 SetPrimitiveField<Primitive::kPrimDouble>(env, javaField, javaObj, value);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800400}
Elliott Hughes33203b52011-09-20 19:42:01 -0700401
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700402static void Field_setFloat(JNIEnv* env, jobject javaField, jobject javaObj, jfloat f) {
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700403 JValue value;
404 value.SetF(f);
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700405 SetPrimitiveField<Primitive::kPrimFloat>(env, javaField, javaObj, value);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800406}
407
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700408static void Field_setInt(JNIEnv* env, jobject javaField, jobject javaObj, jint i) {
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700409 JValue value;
410 value.SetI(i);
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700411 SetPrimitiveField<Primitive::kPrimInt>(env, javaField, javaObj, value);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800412}
413
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700414static void Field_setLong(JNIEnv* env, jobject javaField, jobject javaObj, jlong j) {
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700415 JValue value;
416 value.SetJ(j);
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700417 SetPrimitiveField<Primitive::kPrimLong>(env, javaField, javaObj, value);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800418}
419
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700420static void Field_setShort(JNIEnv* env, jobject javaField, jobject javaObj, jshort s) {
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700421 JValue value;
422 value.SetS(s);
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700423 SetPrimitiveField<Primitive::kPrimShort>(env, javaField, javaObj, value);
Elliott Hughes33203b52011-09-20 19:42:01 -0700424}
425
Jeff Hao13e748b2015-08-25 20:44:19 +0000426static jobject Field_getAnnotationNative(JNIEnv* env, jobject javaField, jclass annotationType) {
427 ScopedFastNativeObjectAccess soa(env);
428 StackHandleScope<1> hs(soa.Self());
429 ArtField* field = soa.Decode<mirror::Field*>(javaField)->GetArtField();
Nicolas Geoffray3a090922015-11-24 09:17:30 +0000430 if (field->GetDeclaringClass()->IsProxyClass()) {
Jeff Hao13e748b2015-08-25 20:44:19 +0000431 return nullptr;
432 }
433 Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class*>(annotationType)));
David Sehr9323e6e2016-09-13 08:58:35 -0700434 return soa.AddLocalReference<jobject>(annotations::GetAnnotationForField(field, klass));
Jeff Hao13e748b2015-08-25 20:44:19 +0000435}
436
437static jobjectArray Field_getDeclaredAnnotations(JNIEnv* env, jobject javaField) {
438 ScopedFastNativeObjectAccess soa(env);
439 ArtField* field = soa.Decode<mirror::Field*>(javaField)->GetArtField();
Nicolas Geoffray3a090922015-11-24 09:17:30 +0000440 if (field->GetDeclaringClass()->IsProxyClass()) {
Jeff Hao13e748b2015-08-25 20:44:19 +0000441 // Return an empty array instead of a null pointer.
442 mirror::Class* annotation_array_class =
443 soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_annotation_Annotation__array);
444 mirror::ObjectArray<mirror::Object>* empty_array =
445 mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), annotation_array_class, 0);
446 return soa.AddLocalReference<jobjectArray>(empty_array);
447 }
David Sehr9323e6e2016-09-13 08:58:35 -0700448 return soa.AddLocalReference<jobjectArray>(annotations::GetAnnotationsForField(field));
Jeff Hao13e748b2015-08-25 20:44:19 +0000449}
450
451static jobjectArray Field_getSignatureAnnotation(JNIEnv* env, jobject javaField) {
452 ScopedFastNativeObjectAccess soa(env);
453 ArtField* field = soa.Decode<mirror::Field*>(javaField)->GetArtField();
Nicolas Geoffray3a090922015-11-24 09:17:30 +0000454 if (field->GetDeclaringClass()->IsProxyClass()) {
Jeff Hao13e748b2015-08-25 20:44:19 +0000455 return nullptr;
456 }
David Sehr9323e6e2016-09-13 08:58:35 -0700457 return soa.AddLocalReference<jobjectArray>(annotations::GetSignatureAnnotationForField(field));
Jeff Hao13e748b2015-08-25 20:44:19 +0000458}
459
460static jboolean Field_isAnnotationPresentNative(JNIEnv* env, jobject javaField,
461 jclass annotationType) {
462 ScopedFastNativeObjectAccess soa(env);
463 StackHandleScope<1> hs(soa.Self());
464 ArtField* field = soa.Decode<mirror::Field*>(javaField)->GetArtField();
Nicolas Geoffray3a090922015-11-24 09:17:30 +0000465 if (field->GetDeclaringClass()->IsProxyClass()) {
Jeff Hao13e748b2015-08-25 20:44:19 +0000466 return false;
467 }
468 Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class*>(annotationType)));
David Sehr9323e6e2016-09-13 08:58:35 -0700469 return annotations::IsFieldAnnotationPresent(field, klass);
Jeff Hao13e748b2015-08-25 20:44:19 +0000470}
471
Brian Carlstromf867b6f2011-09-16 12:17:25 -0700472static JNINativeMethod gMethods[] = {
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700473 NATIVE_METHOD(Field, get, "!(Ljava/lang/Object;)Ljava/lang/Object;"),
474 NATIVE_METHOD(Field, getBoolean, "!(Ljava/lang/Object;)Z"),
475 NATIVE_METHOD(Field, getByte, "!(Ljava/lang/Object;)B"),
476 NATIVE_METHOD(Field, getChar, "!(Ljava/lang/Object;)C"),
Jeff Hao13e748b2015-08-25 20:44:19 +0000477 NATIVE_METHOD(Field, getAnnotationNative,
478 "!(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;"),
479 NATIVE_METHOD(Field, getDeclaredAnnotations, "!()[Ljava/lang/annotation/Annotation;"),
480 NATIVE_METHOD(Field, getSignatureAnnotation, "!()[Ljava/lang/String;"),
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700481 NATIVE_METHOD(Field, getDouble, "!(Ljava/lang/Object;)D"),
482 NATIVE_METHOD(Field, getFloat, "!(Ljava/lang/Object;)F"),
483 NATIVE_METHOD(Field, getInt, "!(Ljava/lang/Object;)I"),
484 NATIVE_METHOD(Field, getLong, "!(Ljava/lang/Object;)J"),
485 NATIVE_METHOD(Field, getShort, "!(Ljava/lang/Object;)S"),
Jeff Hao13e748b2015-08-25 20:44:19 +0000486 NATIVE_METHOD(Field, isAnnotationPresentNative, "!(Ljava/lang/Class;)Z"),
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700487 NATIVE_METHOD(Field, set, "!(Ljava/lang/Object;Ljava/lang/Object;)V"),
488 NATIVE_METHOD(Field, setBoolean, "!(Ljava/lang/Object;Z)V"),
489 NATIVE_METHOD(Field, setByte, "!(Ljava/lang/Object;B)V"),
490 NATIVE_METHOD(Field, setChar, "!(Ljava/lang/Object;C)V"),
491 NATIVE_METHOD(Field, setDouble, "!(Ljava/lang/Object;D)V"),
492 NATIVE_METHOD(Field, setFloat, "!(Ljava/lang/Object;F)V"),
493 NATIVE_METHOD(Field, setInt, "!(Ljava/lang/Object;I)V"),
494 NATIVE_METHOD(Field, setLong, "!(Ljava/lang/Object;J)V"),
495 NATIVE_METHOD(Field, setShort, "!(Ljava/lang/Object;S)V"),
Brian Carlstromf867b6f2011-09-16 12:17:25 -0700496};
497
Brian Carlstromf867b6f2011-09-16 12:17:25 -0700498void register_java_lang_reflect_Field(JNIEnv* env) {
Elliott Hugheseac76672012-05-24 21:56:51 -0700499 REGISTER_NATIVE_METHODS("java/lang/reflect/Field");
Brian Carlstromf867b6f2011-09-16 12:17:25 -0700500}
501
502} // namespace art