java_lang_reflect_Field.cc revision 2dd0e2cea360bc9206eb88ecc40d259e796c239d
1f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom/* 2f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom * Copyright (C) 2008 The Android Open Source Project 3f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom * 4f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License"); 5f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom * you may not use this file except in compliance with the License. 6f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom * You may obtain a copy of the License at 7f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom * 8f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom * http://www.apache.org/licenses/LICENSE-2.0 9f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom * 10f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom * Unless required by applicable law or agreed to in writing, software 11f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS, 12f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom * See the License for the specific language governing permissions and 14f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom * limitations under the License. 15f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom */ 16f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom 17f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom#include "class_linker.h" 182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "class_linker-inl.h" 19eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes#include "jni_internal.h" 202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/field.h" 212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/field-inl.h" 226d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h" 23418d20fc407052d4152157f61e7453359f902383Elliott Hughes#include "reflection.h" 2400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h" 25f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom 26f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstromnamespace art { 27f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom 282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic bool GetFieldValue(const ScopedObjectAccess& soa, mirror::Object* o, mirror::Field* f, 2900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue& value, bool allow_references) 30b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 31f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes DCHECK_EQ(value.GetJ(), 0LL); 3200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(f->GetDeclaringClass(), 3300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers true, true)) { 34923e8b8e936ead33408e111682aa9372e3a7ed43Elliott Hughes return false; 35923e8b8e936ead33408e111682aa9372e3a7ed43Elliott Hughes } 366d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers switch (FieldHelper(f).GetTypeAsPrimitiveType()) { 376b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimBoolean: 38f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetZ(f->GetBoolean(o)); 3933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 406b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimByte: 41f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetB(f->GetByte(o)); 4233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 436b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimChar: 44f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetC(f->GetChar(o)); 4533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 466b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimDouble: 47f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetD(f->GetDouble(o)); 4833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 496b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimFloat: 50f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetF(f->GetFloat(o)); 5133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 526b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimInt: 53f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetI(f->GetInt(o)); 5433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 556b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimLong: 56f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetJ(f->GetLong(o)); 5733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 586b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimShort: 59f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetS(f->GetShort(o)); 6033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 616b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimNot: 6233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes if (allow_references) { 63f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetL(f->GetObject(o)); 6433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 6533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 6633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes // Else break to report an error. 6733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes break; 686b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimVoid: 6933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes // Never okay. 7033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes break; 7133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 7200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Self()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;", 7333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes "Not a primitive field: %s", PrettyField(f).c_str()); 7433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return false; 7533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 7633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 772dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic bool CheckReceiver(const ScopedObjectAccess& soa, jobject javaObj, mirror::Field* f, 782dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Object*& o) 79b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 80ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes if (f->IsStatic()) { 812fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers o = f->GetDeclaringClass(); 82ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes return true; 83ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes } 84ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes 852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers o = soa.Decode<mirror::Object*>(javaObj); 862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* declaringClass = f->GetDeclaringClass(); 87eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes if (!VerifyObjectInClass(o, declaringClass)) { 88ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes return false; 89ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes } 90ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes return true; 91ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes} 92ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes 930512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jobject Field_get(JNIEnv* env, jobject javaField, jobject javaObj) { 9400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 952dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Field* f = soa.DecodeField(env->FromReflectedField(javaField)); 962dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Object* o = NULL; 9700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!CheckReceiver(soa, javaObj, f, o)) { 986d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return NULL; 996d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 1006d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 1016d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers // Get the field's value, boxing if necessary. 1021d878f3e1c39162496d7c061f7f6710e414d182bElliott Hughes JValue value; 10300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!GetFieldValue(soa, o, f, value, true)) { 1046d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return NULL; 1056d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 106af6e67a4816d2593586115b89faa659225363246Ian Rogers return 107af6e67a4816d2593586115b89faa659225363246Ian Rogers soa.AddLocalReference<jobject>(BoxPrimitive(FieldHelper(f).GetTypeAsPrimitiveType(), value)); 1086d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers} 1096d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 1100512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic JValue GetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, char dst_descriptor) { 11100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 1122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Field* f = soa.DecodeField(env->FromReflectedField(javaField)); 1132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Object* o = NULL; 11400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!CheckReceiver(soa, javaObj, f, o)) { 115ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes return JValue(); 11633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 11733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 11833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes // Read the value. 1191d878f3e1c39162496d7c061f7f6710e414d182bElliott Hughes JValue field_value; 12000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!GetFieldValue(soa, o, f, field_value, false)) { 12133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return JValue(); 12233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 12333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 12433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes // Widen it if necessary (and possible). 12533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes JValue wide_value; 1262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* dst_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(dst_descriptor); 1276d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers if (!ConvertPrimitiveValue(FieldHelper(f).GetTypeAsPrimitiveType(), dst_type->GetPrimitiveType(), 1286b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom field_value, wide_value)) { 12933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return JValue(); 13033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 13133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return wide_value; 13233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 13333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1340512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jboolean Field_getBoolean(JNIEnv* env, jobject javaField, jobject javaObj) { 135f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'Z').GetZ(); 13633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 13733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1380512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jbyte Field_getByte(JNIEnv* env, jobject javaField, jobject javaObj) { 139f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'B').GetB(); 14033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 14133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1420512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jchar Field_getChar(JNIEnv* env, jobject javaField, jobject javaObj) { 143f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'C').GetC(); 14433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 14533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1460512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jdouble Field_getDouble(JNIEnv* env, jobject javaField, jobject javaObj) { 147f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'D').GetD(); 14833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 14933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1500512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jfloat Field_getFloat(JNIEnv* env, jobject javaField, jobject javaObj) { 151f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'F').GetF(); 15233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 15333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1540512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jint Field_getInt(JNIEnv* env, jobject javaField, jobject javaObj) { 155f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'I').GetI(); 15633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 15733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1580512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jlong Field_getLong(JNIEnv* env, jobject javaField, jobject javaObj) { 159f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'J').GetJ(); 16033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 16133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1620512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jshort Field_getShort(JNIEnv* env, jobject javaField, jobject javaObj) { 163f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'S').GetS(); 16433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 16533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1662dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic void SetFieldValue(mirror::Object* o, mirror::Field* f, const JValue& new_value, 1672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers bool allow_references) 168b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 16900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(f->GetDeclaringClass(), 17000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers true, true)) { 171923e8b8e936ead33408e111682aa9372e3a7ed43Elliott Hughes return; 172923e8b8e936ead33408e111682aa9372e3a7ed43Elliott Hughes } 1736d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers switch (FieldHelper(f).GetTypeAsPrimitiveType()) { 1746b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimBoolean: 175f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetBoolean(o, new_value.GetZ()); 176fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1776b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimByte: 178f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetByte(o, new_value.GetB()); 179fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1806b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimChar: 181f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetChar(o, new_value.GetC()); 182fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1836b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimDouble: 184f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetDouble(o, new_value.GetD()); 185fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1866b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimFloat: 187f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetFloat(o, new_value.GetF()); 188fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1896b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimInt: 190f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetInt(o, new_value.GetI()); 191fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1926b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimLong: 193f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetLong(o, new_value.GetJ()); 194fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1956b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimShort: 196f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetShort(o, new_value.GetS()); 197fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1986b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimNot: 19933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes if (allow_references) { 200f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetObject(o, new_value.GetL()); 201fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 20233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 203fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes // Else fall through to report an error. 2046b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimVoid: 20533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes // Never okay. 2065cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;", 207fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes "Not a primitive field: %s", PrettyField(f).c_str()); 208fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes return; 209fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes } 210fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes 211fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes // Special handling for final fields on SMP systems. 212fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes // We need a store/store barrier here (JMM requirement). 213fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes if (f->IsFinal()) { 214fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes ANDROID_MEMBAR_STORE(); 21533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 21633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 21733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 2180512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void Field_set(JNIEnv* env, jobject javaField, jobject javaObj, jobject javaValue) { 21900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 2202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Field* f = soa.DecodeField(env->FromReflectedField(javaField)); 2216d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 2226d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers // Unbox the value, if necessary. 2232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Object* boxed_value = soa.Decode<mirror::Object*>(javaValue); 2246d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers JValue unboxed_value; 225aaa5edcf2deb1bddcbf5fb27820ad2240ac5b4f2Elliott Hughes if (!UnboxPrimitiveForField(boxed_value, FieldHelper(f).GetType(), unboxed_value, f)) { 2266d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return; 2276d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 2286d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 2296d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers // Check that the receiver is non-null and an instance of the field's declaring class. 2302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Object* o = NULL; 23100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!CheckReceiver(soa, javaObj, f, o)) { 2326d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return; 2336d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 2346d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 2356d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers SetFieldValue(o, f, unboxed_value, true); 2366d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers} 2376d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 2380512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void SetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, char src_descriptor, 2390512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughes const JValue& new_value) { 24000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 2412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Field* f = soa.DecodeField(env->FromReflectedField(javaField)); 2422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Object* o = NULL; 24300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!CheckReceiver(soa, javaObj, f, o)) { 244ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes return; 24533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 2466d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers FieldHelper fh(f); 2476d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers if (!fh.IsPrimitiveType()) { 24800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Self()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;", 249c129a6b44193ac3a872f852a69d336e0e7ed8640Jesse Wilson "Not a primitive field: %s", PrettyField(f).c_str()); 250c129a6b44193ac3a872f852a69d336e0e7ed8640Jesse Wilson return; 251c129a6b44193ac3a872f852a69d336e0e7ed8640Jesse Wilson } 25233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 25333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes // Widen the value if necessary (and possible). 25433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes JValue wide_value; 2552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* src_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(src_descriptor); 2566d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers if (!ConvertPrimitiveValue(src_type->GetPrimitiveType(), fh.GetTypeAsPrimitiveType(), 2576b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom new_value, wide_value)) { 25833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return; 25933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 26033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 26133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes // Write the value. 26233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes SetFieldValue(o, f, wide_value, false); 26333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 26433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 265f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setBoolean(JNIEnv* env, jobject javaField, jobject javaObj, jboolean z) { 266f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 267f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetZ(z); 268f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'Z', value); 2696d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers} 2706d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 271f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setByte(JNIEnv* env, jobject javaField, jobject javaObj, jbyte b) { 272f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 273f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetB(b); 274f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'B', value); 27533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 27633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 277f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setChar(JNIEnv* env, jobject javaField, jobject javaObj, jchar c) { 278f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 279f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetC(c); 280f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'C', value); 28133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 28233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 283f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setDouble(JNIEnv* env, jobject javaField, jobject javaObj, jdouble d) { 284f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 285f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetD(d); 286f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'D', value); 28733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 28833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 289f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setFloat(JNIEnv* env, jobject javaField, jobject javaObj, jfloat f) { 290f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 291f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetF(f); 292f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'F', value); 29333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 29433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 295f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setInt(JNIEnv* env, jobject javaField, jobject javaObj, jint i) { 296f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 297f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetI(i); 298f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'I', value); 29933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 30033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 301f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setLong(JNIEnv* env, jobject javaField, jobject javaObj, jlong j) { 302f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 303f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetJ(j); 304f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'J', value); 30533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 30633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 307f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setShort(JNIEnv* env, jobject javaField, jobject javaObj, jshort s) { 308f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 309f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetS(s); 310f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'S', value); 31133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 31233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 313f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstromstatic JNINativeMethod gMethods[] = { 3146d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, get, "(Ljava/lang/Object;)Ljava/lang/Object;"), 3156d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, getBoolean, "(Ljava/lang/Object;)Z"), 3166d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, getByte, "(Ljava/lang/Object;)B"), 3176d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, getChar, "(Ljava/lang/Object;)C"), 3186d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, getDouble, "(Ljava/lang/Object;)D"), 3196d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, getFloat, "(Ljava/lang/Object;)F"), 3206d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, getInt, "(Ljava/lang/Object;)I"), 3216d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, getLong, "(Ljava/lang/Object;)J"), 3226d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, getShort, "(Ljava/lang/Object;)S"), 3236d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, set, "(Ljava/lang/Object;Ljava/lang/Object;)V"), 3246d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, setBoolean, "(Ljava/lang/Object;Z)V"), 3256d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, setByte, "(Ljava/lang/Object;B)V"), 3266d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, setChar, "(Ljava/lang/Object;C)V"), 3276d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, setDouble, "(Ljava/lang/Object;D)V"), 3286d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, setFloat, "(Ljava/lang/Object;F)V"), 3296d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, setInt, "(Ljava/lang/Object;I)V"), 3306d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, setLong, "(Ljava/lang/Object;J)V"), 3316d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, setShort, "(Ljava/lang/Object;S)V"), 332f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom}; 333f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom 334f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstromvoid register_java_lang_reflect_Field(JNIEnv* env) { 335eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes REGISTER_NATIVE_METHODS("java/lang/reflect/Field"); 336f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom} 337f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom 338f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom} // namespace art 339