java_lang_reflect_Field.cc revision b726dcb581bf72da46527378ccb6889020f0e6e9
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" 18eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes#include "jni_internal.h" 19f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom#include "object.h" 206d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h" 21418d20fc407052d4152157f61e7453359f902383Elliott Hughes#include "reflection.h" 2200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h" 23f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom 24f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstromnamespace art { 25f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom 2600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic bool GetFieldValue(const ScopedObjectAccess& soa, Object* o, Field* f, 2700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue& value, bool allow_references) 28b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 29f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes DCHECK_EQ(value.GetJ(), 0LL); 3000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(f->GetDeclaringClass(), 3100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers true, true)) { 32923e8b8e936ead33408e111682aa9372e3a7ed43Elliott Hughes return false; 33923e8b8e936ead33408e111682aa9372e3a7ed43Elliott Hughes } 346d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers switch (FieldHelper(f).GetTypeAsPrimitiveType()) { 356b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimBoolean: 36f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetZ(f->GetBoolean(o)); 3733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 386b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimByte: 39f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetB(f->GetByte(o)); 4033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 416b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimChar: 42f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetC(f->GetChar(o)); 4333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 446b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimDouble: 45f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetD(f->GetDouble(o)); 4633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 476b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimFloat: 48f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetF(f->GetFloat(o)); 4933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 506b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimInt: 51f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetI(f->GetInt(o)); 5233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 536b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimLong: 54f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetJ(f->GetLong(o)); 5533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 566b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimShort: 57f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetS(f->GetShort(o)); 5833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 596b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimNot: 6033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes if (allow_references) { 61f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetL(f->GetObject(o)); 6233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 6333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 6433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes // Else break to report an error. 6533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes break; 666b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimVoid: 6733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes // Never okay. 6833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes break; 6933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 7000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Self()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;", 7133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes "Not a primitive field: %s", PrettyField(f).c_str()); 7233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return false; 7333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 7433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 7500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic bool CheckReceiver(const ScopedObjectAccess& soa, jobject javaObj, Field* f, 7600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object*& o) 77b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 78ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes if (f->IsStatic()) { 79ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes o = NULL; 80ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes return true; 81ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes } 82ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes 8300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers o = soa.Decode<Object*>(javaObj); 846d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers Class* declaringClass = f->GetDeclaringClass(); 85eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes if (!VerifyObjectInClass(o, declaringClass)) { 86ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes return false; 87ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes } 88ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes return true; 89ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes} 90ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes 910512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jobject Field_get(JNIEnv* env, jobject javaField, jobject javaObj) { 9200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 9300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Field* f = soa.DecodeField(env->FromReflectedField(javaField)); 946d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers Object* o = NULL; 9500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!CheckReceiver(soa, javaObj, f, o)) { 966d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return NULL; 976d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 986d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 996d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers // Get the field's value, boxing if necessary. 1001d878f3e1c39162496d7c061f7f6710e414d182bElliott Hughes JValue value; 10100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!GetFieldValue(soa, o, f, value, true)) { 1026d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return NULL; 1036d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 104dbac3090ace708eb27c707d4b72efc48c069129cElliott Hughes BoxPrimitive(FieldHelper(f).GetTypeAsPrimitiveType(), value); 1056d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 10600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jobject>(value.GetL()); 1076d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers} 1086d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 1090512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic JValue GetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, char dst_descriptor) { 11000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 11100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Field* f = soa.DecodeField(env->FromReflectedField(javaField)); 112ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes Object* o = NULL; 11300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!CheckReceiver(soa, javaObj, f, o)) { 114ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes return JValue(); 11533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 11633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 11733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes // Read the value. 1181d878f3e1c39162496d7c061f7f6710e414d182bElliott Hughes JValue field_value; 11900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!GetFieldValue(soa, o, f, field_value, false)) { 12033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return JValue(); 12133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 12233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 12333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes // Widen it if necessary (and possible). 12433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes JValue wide_value; 125582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughes Class* dst_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(dst_descriptor); 1266d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers if (!ConvertPrimitiveValue(FieldHelper(f).GetTypeAsPrimitiveType(), dst_type->GetPrimitiveType(), 1276b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom field_value, wide_value)) { 12833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return JValue(); 12933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 13033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return wide_value; 13133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 13233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1330512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jboolean Field_getBoolean(JNIEnv* env, jobject javaField, jobject javaObj) { 134f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'Z').GetZ(); 13533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 13633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1370512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jbyte Field_getByte(JNIEnv* env, jobject javaField, jobject javaObj) { 138f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'B').GetB(); 13933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 14033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1410512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jchar Field_getChar(JNIEnv* env, jobject javaField, jobject javaObj) { 142f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'C').GetC(); 14333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 14433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1450512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jdouble Field_getDouble(JNIEnv* env, jobject javaField, jobject javaObj) { 146f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'D').GetD(); 14733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 14833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1490512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jfloat Field_getFloat(JNIEnv* env, jobject javaField, jobject javaObj) { 150f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'F').GetF(); 15133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 15233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1530512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jint Field_getInt(JNIEnv* env, jobject javaField, jobject javaObj) { 154f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'I').GetI(); 15533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 15633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1570512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jlong Field_getLong(JNIEnv* env, jobject javaField, jobject javaObj) { 158f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'J').GetJ(); 15933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 16033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1610512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jshort Field_getShort(JNIEnv* env, jobject javaField, jobject javaObj) { 162f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'S').GetS(); 16333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 16433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 16500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void SetFieldValue(Object* o, Field* f, const JValue& new_value, bool allow_references) 166b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 16700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(f->GetDeclaringClass(), 16800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers true, true)) { 169923e8b8e936ead33408e111682aa9372e3a7ed43Elliott Hughes return; 170923e8b8e936ead33408e111682aa9372e3a7ed43Elliott Hughes } 1716d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers switch (FieldHelper(f).GetTypeAsPrimitiveType()) { 1726b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimBoolean: 173f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetBoolean(o, new_value.GetZ()); 174fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1756b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimByte: 176f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetByte(o, new_value.GetB()); 177fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1786b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimChar: 179f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetChar(o, new_value.GetC()); 180fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1816b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimDouble: 182f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetDouble(o, new_value.GetD()); 183fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1846b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimFloat: 185f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetFloat(o, new_value.GetF()); 186fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1876b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimInt: 188f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetInt(o, new_value.GetI()); 189fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1906b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimLong: 191f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetLong(o, new_value.GetJ()); 192fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1936b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimShort: 194f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetShort(o, new_value.GetS()); 195fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1966b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimNot: 19733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes if (allow_references) { 198f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetObject(o, new_value.GetL()); 199fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 20033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 201fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes // Else fall through to report an error. 2026b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimVoid: 20333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes // Never okay. 2045cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;", 205fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes "Not a primitive field: %s", PrettyField(f).c_str()); 206fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes return; 207fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes } 208fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes 209fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes // Special handling for final fields on SMP systems. 210fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes // We need a store/store barrier here (JMM requirement). 211fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes if (f->IsFinal()) { 212fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes ANDROID_MEMBAR_STORE(); 21333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 21433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 21533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 2160512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void Field_set(JNIEnv* env, jobject javaField, jobject javaObj, jobject javaValue) { 21700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 21800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Field* f = soa.DecodeField(env->FromReflectedField(javaField)); 2196d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 2206d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers // Unbox the value, if necessary. 22100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* boxed_value = soa.Decode<Object*>(javaValue); 2226d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers JValue unboxed_value; 223aaa5edcf2deb1bddcbf5fb27820ad2240ac5b4f2Elliott Hughes if (!UnboxPrimitiveForField(boxed_value, FieldHelper(f).GetType(), unboxed_value, f)) { 2246d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return; 2256d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 2266d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 2276d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers // Check that the receiver is non-null and an instance of the field's declaring class. 2286d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers Object* o = NULL; 22900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!CheckReceiver(soa, javaObj, f, o)) { 2306d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return; 2316d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 2326d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 2336d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers SetFieldValue(o, f, unboxed_value, true); 2346d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers} 2356d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 2360512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void SetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, char src_descriptor, 2370512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughes const JValue& new_value) { 23800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 23900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Field* f = soa.DecodeField(env->FromReflectedField(javaField)); 240ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes Object* o = NULL; 24100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!CheckReceiver(soa, javaObj, f, o)) { 242ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes return; 24333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 2446d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers FieldHelper fh(f); 2456d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers if (!fh.IsPrimitiveType()) { 24600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Self()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;", 247c129a6b44193ac3a872f852a69d336e0e7ed8640Jesse Wilson "Not a primitive field: %s", PrettyField(f).c_str()); 248c129a6b44193ac3a872f852a69d336e0e7ed8640Jesse Wilson return; 249c129a6b44193ac3a872f852a69d336e0e7ed8640Jesse Wilson } 25033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 25133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes // Widen the value if necessary (and possible). 25233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes JValue wide_value; 253582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughes Class* src_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(src_descriptor); 2546d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers if (!ConvertPrimitiveValue(src_type->GetPrimitiveType(), fh.GetTypeAsPrimitiveType(), 2556b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom new_value, wide_value)) { 25633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return; 25733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 25833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 25933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes // Write the value. 26033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes SetFieldValue(o, f, wide_value, false); 26133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 26233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 263f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setBoolean(JNIEnv* env, jobject javaField, jobject javaObj, jboolean z) { 264f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 265f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetZ(z); 266f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'Z', value); 2676d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers} 2686d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 269f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setByte(JNIEnv* env, jobject javaField, jobject javaObj, jbyte b) { 270f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 271f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetB(b); 272f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'B', value); 27333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 27433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 275f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setChar(JNIEnv* env, jobject javaField, jobject javaObj, jchar c) { 276f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 277f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetC(c); 278f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'C', value); 27933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 28033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 281f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setDouble(JNIEnv* env, jobject javaField, jobject javaObj, jdouble d) { 282f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 283f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetD(d); 284f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'D', value); 28533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 28633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 287f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setFloat(JNIEnv* env, jobject javaField, jobject javaObj, jfloat f) { 288f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 289f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetF(f); 290f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'F', value); 29133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 29233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 293f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setInt(JNIEnv* env, jobject javaField, jobject javaObj, jint i) { 294f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 295f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetI(i); 296f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'I', value); 29733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 29833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 299f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setLong(JNIEnv* env, jobject javaField, jobject javaObj, jlong j) { 300f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 301f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetJ(j); 302f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'J', value); 30333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 30433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 305f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setShort(JNIEnv* env, jobject javaField, jobject javaObj, jshort s) { 306f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 307f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetS(s); 308f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'S', value); 30933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 31033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 311f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstromstatic JNINativeMethod gMethods[] = { 3126d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, get, "(Ljava/lang/Object;)Ljava/lang/Object;"), 3136d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, getBoolean, "(Ljava/lang/Object;)Z"), 3146d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, getByte, "(Ljava/lang/Object;)B"), 3156d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, getChar, "(Ljava/lang/Object;)C"), 3166d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, getDouble, "(Ljava/lang/Object;)D"), 3176d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, getFloat, "(Ljava/lang/Object;)F"), 3186d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, getInt, "(Ljava/lang/Object;)I"), 3196d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, getLong, "(Ljava/lang/Object;)J"), 3206d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, getShort, "(Ljava/lang/Object;)S"), 3216d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, set, "(Ljava/lang/Object;Ljava/lang/Object;)V"), 3226d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, setBoolean, "(Ljava/lang/Object;Z)V"), 3236d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, setByte, "(Ljava/lang/Object;B)V"), 3246d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, setChar, "(Ljava/lang/Object;C)V"), 3256d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, setDouble, "(Ljava/lang/Object;D)V"), 3266d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, setFloat, "(Ljava/lang/Object;F)V"), 3276d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, setInt, "(Ljava/lang/Object;I)V"), 3286d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, setLong, "(Ljava/lang/Object;J)V"), 3296d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, setShort, "(Ljava/lang/Object;S)V"), 330f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom}; 331f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom 332f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstromvoid register_java_lang_reflect_Field(JNIEnv* env) { 333eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes REGISTER_NATIVE_METHODS("java/lang/reflect/Field"); 334f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom} 335f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom 336f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom} // namespace art 337