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 "class_linker.h" 18 #include "class_linker-inl.h" 19 #include "common_throws.h" 20 #include "dex_file-inl.h" 21 #include "jni_internal.h" 22 #include "mirror/art_field-inl.h" 23 #include "mirror/class-inl.h" 24 #include "object_utils.h" 25 #include "reflection.h" 26 #include "scoped_thread_state_change.h" 27 28 namespace art { 29 30 static bool GetFieldValue(const ScopedObjectAccess& soa, mirror::Object* o, mirror::ArtField* f, 31 JValue& value, bool allow_references) 32 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 33 DCHECK_EQ(value.GetJ(), 0LL); 34 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(f->GetDeclaringClass(), 35 true, true)) { 36 return false; 37 } 38 switch (FieldHelper(f).GetTypeAsPrimitiveType()) { 39 case Primitive::kPrimBoolean: 40 value.SetZ(f->GetBoolean(o)); 41 return true; 42 case Primitive::kPrimByte: 43 value.SetB(f->GetByte(o)); 44 return true; 45 case Primitive::kPrimChar: 46 value.SetC(f->GetChar(o)); 47 return true; 48 case Primitive::kPrimDouble: 49 value.SetD(f->GetDouble(o)); 50 return true; 51 case Primitive::kPrimFloat: 52 value.SetF(f->GetFloat(o)); 53 return true; 54 case Primitive::kPrimInt: 55 value.SetI(f->GetInt(o)); 56 return true; 57 case Primitive::kPrimLong: 58 value.SetJ(f->GetLong(o)); 59 return true; 60 case Primitive::kPrimShort: 61 value.SetS(f->GetShort(o)); 62 return true; 63 case Primitive::kPrimNot: 64 if (allow_references) { 65 value.SetL(f->GetObject(o)); 66 return true; 67 } 68 // Else break to report an error. 69 break; 70 case Primitive::kPrimVoid: 71 // Never okay. 72 break; 73 } 74 ThrowIllegalArgumentException(NULL, 75 StringPrintf("Not a primitive field: %s", 76 PrettyField(f).c_str()).c_str()); 77 return false; 78 } 79 80 static bool CheckReceiver(const ScopedObjectAccess& soa, jobject j_rcvr, mirror::ArtField* f, 81 mirror::Object*& class_or_rcvr) 82 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 83 if (f->IsStatic()) { 84 class_or_rcvr = f->GetDeclaringClass(); 85 return true; 86 } 87 88 class_or_rcvr = soa.Decode<mirror::Object*>(j_rcvr); 89 mirror::Class* declaringClass = f->GetDeclaringClass(); 90 if (!VerifyObjectInClass(class_or_rcvr, declaringClass)) { 91 return false; 92 } 93 return true; 94 } 95 96 static jobject Field_get(JNIEnv* env, jobject javaField, jobject javaObj) { 97 ScopedObjectAccess soa(env); 98 mirror::ArtField* f = soa.DecodeField(env->FromReflectedField(javaField)); 99 mirror::Object* o = NULL; 100 if (!CheckReceiver(soa, javaObj, f, o)) { 101 return NULL; 102 } 103 104 // Get the field's value, boxing if necessary. 105 JValue value; 106 if (!GetFieldValue(soa, o, f, value, true)) { 107 return NULL; 108 } 109 return 110 soa.AddLocalReference<jobject>(BoxPrimitive(FieldHelper(f).GetTypeAsPrimitiveType(), value)); 111 } 112 113 static JValue GetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, 114 char dst_descriptor) { 115 ScopedObjectAccess soa(env); 116 mirror::ArtField* f = soa.DecodeField(env->FromReflectedField(javaField)); 117 mirror::Object* o = NULL; 118 if (!CheckReceiver(soa, javaObj, f, o)) { 119 return JValue(); 120 } 121 122 // Read the value. 123 JValue field_value; 124 if (!GetFieldValue(soa, o, f, field_value, false)) { 125 return JValue(); 126 } 127 128 // Widen it if necessary (and possible). 129 JValue wide_value; 130 mirror::Class* dst_type = 131 Runtime::Current()->GetClassLinker()->FindPrimitiveClass(dst_descriptor); 132 if (!ConvertPrimitiveValue(NULL, false, FieldHelper(f).GetTypeAsPrimitiveType(), 133 dst_type->GetPrimitiveType(), field_value, wide_value)) { 134 return JValue(); 135 } 136 return wide_value; 137 } 138 139 static jboolean Field_getBoolean(JNIEnv* env, jobject javaField, jobject javaObj) { 140 return GetPrimitiveField(env, javaField, javaObj, 'Z').GetZ(); 141 } 142 143 static jbyte Field_getByte(JNIEnv* env, jobject javaField, jobject javaObj) { 144 return GetPrimitiveField(env, javaField, javaObj, 'B').GetB(); 145 } 146 147 static jchar Field_getChar(JNIEnv* env, jobject javaField, jobject javaObj) { 148 return GetPrimitiveField(env, javaField, javaObj, 'C').GetC(); 149 } 150 151 static jdouble Field_getDouble(JNIEnv* env, jobject javaField, jobject javaObj) { 152 return GetPrimitiveField(env, javaField, javaObj, 'D').GetD(); 153 } 154 155 static jfloat Field_getFloat(JNIEnv* env, jobject javaField, jobject javaObj) { 156 return GetPrimitiveField(env, javaField, javaObj, 'F').GetF(); 157 } 158 159 static jint Field_getInt(JNIEnv* env, jobject javaField, jobject javaObj) { 160 return GetPrimitiveField(env, javaField, javaObj, 'I').GetI(); 161 } 162 163 static jlong Field_getLong(JNIEnv* env, jobject javaField, jobject javaObj) { 164 return GetPrimitiveField(env, javaField, javaObj, 'J').GetJ(); 165 } 166 167 static jshort Field_getShort(JNIEnv* env, jobject javaField, jobject javaObj) { 168 return GetPrimitiveField(env, javaField, javaObj, 'S').GetS(); 169 } 170 171 static void SetFieldValue(mirror::Object* o, mirror::ArtField* f, const JValue& new_value, 172 bool allow_references) 173 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 174 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(f->GetDeclaringClass(), 175 true, true)) { 176 return; 177 } 178 switch (FieldHelper(f).GetTypeAsPrimitiveType()) { 179 case Primitive::kPrimBoolean: 180 f->SetBoolean(o, new_value.GetZ()); 181 break; 182 case Primitive::kPrimByte: 183 f->SetByte(o, new_value.GetB()); 184 break; 185 case Primitive::kPrimChar: 186 f->SetChar(o, new_value.GetC()); 187 break; 188 case Primitive::kPrimDouble: 189 f->SetDouble(o, new_value.GetD()); 190 break; 191 case Primitive::kPrimFloat: 192 f->SetFloat(o, new_value.GetF()); 193 break; 194 case Primitive::kPrimInt: 195 f->SetInt(o, new_value.GetI()); 196 break; 197 case Primitive::kPrimLong: 198 f->SetLong(o, new_value.GetJ()); 199 break; 200 case Primitive::kPrimShort: 201 f->SetShort(o, new_value.GetS()); 202 break; 203 case Primitive::kPrimNot: 204 if (allow_references) { 205 f->SetObject(o, new_value.GetL()); 206 break; 207 } 208 // Else fall through to report an error. 209 case Primitive::kPrimVoid: 210 // Never okay. 211 ThrowIllegalArgumentException(NULL, StringPrintf("Not a primitive field: %s", 212 PrettyField(f).c_str()).c_str()); 213 return; 214 } 215 216 // Special handling for final fields on SMP systems. 217 // We need a store/store barrier here (JMM requirement). 218 if (f->IsFinal()) { 219 ANDROID_MEMBAR_STORE(); 220 } 221 } 222 223 static void Field_set(JNIEnv* env, jobject javaField, jobject javaObj, jobject javaValue) { 224 ScopedObjectAccess soa(env); 225 mirror::ArtField* f = soa.DecodeField(env->FromReflectedField(javaField)); 226 227 // Unbox the value, if necessary. 228 mirror::Object* boxed_value = soa.Decode<mirror::Object*>(javaValue); 229 JValue unboxed_value; 230 if (!UnboxPrimitiveForField(boxed_value, FieldHelper(f).GetType(), unboxed_value, f)) { 231 return; 232 } 233 234 // Check that the receiver is non-null and an instance of the field's declaring class. 235 mirror::Object* o = NULL; 236 if (!CheckReceiver(soa, javaObj, f, o)) { 237 return; 238 } 239 240 SetFieldValue(o, f, unboxed_value, true); 241 } 242 243 static void SetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, char src_descriptor, 244 const JValue& new_value) { 245 ScopedObjectAccess soa(env); 246 mirror::ArtField* f = soa.DecodeField(env->FromReflectedField(javaField)); 247 mirror::Object* o = NULL; 248 if (!CheckReceiver(soa, javaObj, f, o)) { 249 return; 250 } 251 FieldHelper fh(f); 252 if (!fh.IsPrimitiveType()) { 253 ThrowIllegalArgumentException(NULL, StringPrintf("Not a primitive field: %s", 254 PrettyField(f).c_str()).c_str()); 255 return; 256 } 257 258 // Widen the value if necessary (and possible). 259 JValue wide_value; 260 mirror::Class* src_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(src_descriptor); 261 if (!ConvertPrimitiveValue(NULL, false, src_type->GetPrimitiveType(), fh.GetTypeAsPrimitiveType(), 262 new_value, wide_value)) { 263 return; 264 } 265 266 // Write the value. 267 SetFieldValue(o, f, wide_value, false); 268 } 269 270 static void Field_setBoolean(JNIEnv* env, jobject javaField, jobject javaObj, jboolean z) { 271 JValue value; 272 value.SetZ(z); 273 SetPrimitiveField(env, javaField, javaObj, 'Z', value); 274 } 275 276 static void Field_setByte(JNIEnv* env, jobject javaField, jobject javaObj, jbyte b) { 277 JValue value; 278 value.SetB(b); 279 SetPrimitiveField(env, javaField, javaObj, 'B', value); 280 } 281 282 static void Field_setChar(JNIEnv* env, jobject javaField, jobject javaObj, jchar c) { 283 JValue value; 284 value.SetC(c); 285 SetPrimitiveField(env, javaField, javaObj, 'C', value); 286 } 287 288 static void Field_setDouble(JNIEnv* env, jobject javaField, jobject javaObj, jdouble d) { 289 JValue value; 290 value.SetD(d); 291 SetPrimitiveField(env, javaField, javaObj, 'D', value); 292 } 293 294 static void Field_setFloat(JNIEnv* env, jobject javaField, jobject javaObj, jfloat f) { 295 JValue value; 296 value.SetF(f); 297 SetPrimitiveField(env, javaField, javaObj, 'F', value); 298 } 299 300 static void Field_setInt(JNIEnv* env, jobject javaField, jobject javaObj, jint i) { 301 JValue value; 302 value.SetI(i); 303 SetPrimitiveField(env, javaField, javaObj, 'I', value); 304 } 305 306 static void Field_setLong(JNIEnv* env, jobject javaField, jobject javaObj, jlong j) { 307 JValue value; 308 value.SetJ(j); 309 SetPrimitiveField(env, javaField, javaObj, 'J', value); 310 } 311 312 static void Field_setShort(JNIEnv* env, jobject javaField, jobject javaObj, jshort s) { 313 JValue value; 314 value.SetS(s); 315 SetPrimitiveField(env, javaField, javaObj, 'S', value); 316 } 317 318 static JNINativeMethod gMethods[] = { 319 NATIVE_METHOD(Field, get, "(Ljava/lang/Object;)Ljava/lang/Object;"), 320 NATIVE_METHOD(Field, getBoolean, "(Ljava/lang/Object;)Z"), 321 NATIVE_METHOD(Field, getByte, "(Ljava/lang/Object;)B"), 322 NATIVE_METHOD(Field, getChar, "(Ljava/lang/Object;)C"), 323 NATIVE_METHOD(Field, getDouble, "(Ljava/lang/Object;)D"), 324 NATIVE_METHOD(Field, getFloat, "(Ljava/lang/Object;)F"), 325 NATIVE_METHOD(Field, getInt, "(Ljava/lang/Object;)I"), 326 NATIVE_METHOD(Field, getLong, "(Ljava/lang/Object;)J"), 327 NATIVE_METHOD(Field, getShort, "(Ljava/lang/Object;)S"), 328 NATIVE_METHOD(Field, set, "(Ljava/lang/Object;Ljava/lang/Object;)V"), 329 NATIVE_METHOD(Field, setBoolean, "(Ljava/lang/Object;Z)V"), 330 NATIVE_METHOD(Field, setByte, "(Ljava/lang/Object;B)V"), 331 NATIVE_METHOD(Field, setChar, "(Ljava/lang/Object;C)V"), 332 NATIVE_METHOD(Field, setDouble, "(Ljava/lang/Object;D)V"), 333 NATIVE_METHOD(Field, setFloat, "(Ljava/lang/Object;F)V"), 334 NATIVE_METHOD(Field, setInt, "(Ljava/lang/Object;I)V"), 335 NATIVE_METHOD(Field, setLong, "(Ljava/lang/Object;J)V"), 336 NATIVE_METHOD(Field, setShort, "(Ljava/lang/Object;S)V"), 337 }; 338 339 void register_java_lang_reflect_Field(JNIEnv* env) { 340 REGISTER_NATIVE_METHODS("java/lang/reflect/Field"); 341 } 342 343 } // namespace art 344