java_lang_reflect_Field.cc revision 1eb512d33f94d1dd7ea38263307ba0f7a0dfa653
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" 1962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers#include "common_throws.h" 204f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h" 21eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes#include "jni_internal.h" 22ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include "mirror/art_field-inl.h" 234f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "mirror/class-inl.h" 246d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h" 25418d20fc407052d4152157f61e7453359f902383Elliott Hughes#include "reflection.h" 261eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers#include "scoped_fast_native_object_access.h" 27f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom 28f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstromnamespace art { 29f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom 301eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogersstatic bool GetFieldValue(const ScopedFastNativeObjectAccess& soa, mirror::Object* o, 311eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers mirror::ArtField* f, JValue& value, bool allow_references) 32b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 33f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes DCHECK_EQ(value.GetJ(), 0LL); 3400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(f->GetDeclaringClass(), 3500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers true, true)) { 36923e8b8e936ead33408e111682aa9372e3a7ed43Elliott Hughes return false; 37923e8b8e936ead33408e111682aa9372e3a7ed43Elliott Hughes } 386d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers switch (FieldHelper(f).GetTypeAsPrimitiveType()) { 396b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimBoolean: 40f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetZ(f->GetBoolean(o)); 4133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 426b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimByte: 43f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetB(f->GetByte(o)); 4433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 456b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimChar: 46f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetC(f->GetChar(o)); 4733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 486b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimDouble: 49f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetD(f->GetDouble(o)); 5033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 516b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimFloat: 52f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetF(f->GetFloat(o)); 5333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 546b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimInt: 55f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetI(f->GetInt(o)); 5633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 576b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimLong: 58f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetJ(f->GetLong(o)); 5933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 606b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimShort: 61f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetS(f->GetShort(o)); 6233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 636b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimNot: 6433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes if (allow_references) { 65f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetL(f->GetObject(o)); 6633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 6733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 6833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes // Else break to report an error. 6933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes break; 706b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimVoid: 7133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes // Never okay. 7233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes break; 7333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 7462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowIllegalArgumentException(NULL, 7562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers StringPrintf("Not a primitive field: %s", 7662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PrettyField(f).c_str()).c_str()); 7733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return false; 7833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 7933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 801eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogersstatic bool CheckReceiver(const ScopedFastNativeObjectAccess& soa, jobject j_rcvr, 811eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers mirror::ArtField* f, mirror::Object*& class_or_rcvr) 82b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 83ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes if (f->IsStatic()) { 8462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers class_or_rcvr = f->GetDeclaringClass(); 85ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes return true; 86ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes } 87ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes 8862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers class_or_rcvr = soa.Decode<mirror::Object*>(j_rcvr); 892dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* declaringClass = f->GetDeclaringClass(); 9062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (!VerifyObjectInClass(class_or_rcvr, declaringClass)) { 91ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes return false; 92ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes } 93ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes return true; 94ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes} 95ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes 960512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jobject Field_get(JNIEnv* env, jobject javaField, jobject javaObj) { 971eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers ScopedFastNativeObjectAccess soa(env); 98ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtField* f = soa.DecodeField(env->FromReflectedField(javaField)); 992dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Object* o = NULL; 10000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!CheckReceiver(soa, javaObj, f, o)) { 1016d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return NULL; 1026d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 1036d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 1046d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers // Get the field's value, boxing if necessary. 1051d878f3e1c39162496d7c061f7f6710e414d182bElliott Hughes JValue value; 10600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!GetFieldValue(soa, o, f, value, true)) { 1076d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return NULL; 1086d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 109af6e67a4816d2593586115b89faa659225363246Ian Rogers return 110af6e67a4816d2593586115b89faa659225363246Ian Rogers soa.AddLocalReference<jobject>(BoxPrimitive(FieldHelper(f).GetTypeAsPrimitiveType(), value)); 1116d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers} 1126d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 113ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromstatic JValue GetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, 114ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom char dst_descriptor) { 1151eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers ScopedFastNativeObjectAccess soa(env); 116ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtField* f = soa.DecodeField(env->FromReflectedField(javaField)); 1172dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Object* o = NULL; 11800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!CheckReceiver(soa, javaObj, f, o)) { 119ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes return JValue(); 12033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 12133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 12233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes // Read the value. 1231d878f3e1c39162496d7c061f7f6710e414d182bElliott Hughes JValue field_value; 12400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!GetFieldValue(soa, o, f, field_value, false)) { 12533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return JValue(); 12633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 12733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 12833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes // Widen it if necessary (and possible). 12933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes JValue wide_value; 130ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::Class* dst_type = 131ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom Runtime::Current()->GetClassLinker()->FindPrimitiveClass(dst_descriptor); 13262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (!ConvertPrimitiveValue(NULL, false, FieldHelper(f).GetTypeAsPrimitiveType(), 13362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers dst_type->GetPrimitiveType(), field_value, wide_value)) { 13433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return JValue(); 13533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 13633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return wide_value; 13733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 13833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1390512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jboolean Field_getBoolean(JNIEnv* env, jobject javaField, jobject javaObj) { 140f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'Z').GetZ(); 14133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 14233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1430512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jbyte Field_getByte(JNIEnv* env, jobject javaField, jobject javaObj) { 144f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'B').GetB(); 14533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 14633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1470512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jchar Field_getChar(JNIEnv* env, jobject javaField, jobject javaObj) { 148f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'C').GetC(); 14933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 15033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1510512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jdouble Field_getDouble(JNIEnv* env, jobject javaField, jobject javaObj) { 152f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'D').GetD(); 15333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 15433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1550512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jfloat Field_getFloat(JNIEnv* env, jobject javaField, jobject javaObj) { 156f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'F').GetF(); 15733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 15833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1590512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jint Field_getInt(JNIEnv* env, jobject javaField, jobject javaObj) { 160f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'I').GetI(); 16133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 16233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1630512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jlong Field_getLong(JNIEnv* env, jobject javaField, jobject javaObj) { 164f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'J').GetJ(); 16533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 16633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1670512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jshort Field_getShort(JNIEnv* env, jobject javaField, jobject javaObj) { 168f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'S').GetS(); 16933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 17033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 171ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromstatic void SetFieldValue(mirror::Object* o, mirror::ArtField* f, const JValue& new_value, 1722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers bool allow_references) 173b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 17400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(f->GetDeclaringClass(), 17500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers true, true)) { 176923e8b8e936ead33408e111682aa9372e3a7ed43Elliott Hughes return; 177923e8b8e936ead33408e111682aa9372e3a7ed43Elliott Hughes } 1786d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers switch (FieldHelper(f).GetTypeAsPrimitiveType()) { 1796b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimBoolean: 180f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetBoolean(o, new_value.GetZ()); 181fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1826b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimByte: 183f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetByte(o, new_value.GetB()); 184fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1856b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimChar: 186f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetChar(o, new_value.GetC()); 187fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1886b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimDouble: 189f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetDouble(o, new_value.GetD()); 190fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1916b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimFloat: 192f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetFloat(o, new_value.GetF()); 193fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1946b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimInt: 195f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetInt(o, new_value.GetI()); 196fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1976b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimLong: 198f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetLong(o, new_value.GetJ()); 199fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 2006b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimShort: 201f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetShort(o, new_value.GetS()); 202fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 2036b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimNot: 20433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes if (allow_references) { 205f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetObject(o, new_value.GetL()); 206fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 20733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 208fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes // Else fall through to report an error. 2096b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimVoid: 21033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes // Never okay. 21162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowIllegalArgumentException(NULL, StringPrintf("Not a primitive field: %s", 21262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PrettyField(f).c_str()).c_str()); 213fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes return; 214fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes } 215fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes 216fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes // Special handling for final fields on SMP systems. 217fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes // We need a store/store barrier here (JMM requirement). 218fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes if (f->IsFinal()) { 219fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes ANDROID_MEMBAR_STORE(); 22033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 22133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 22233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 2230512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void Field_set(JNIEnv* env, jobject javaField, jobject javaObj, jobject javaValue) { 2241eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers ScopedFastNativeObjectAccess soa(env); 225ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtField* f = soa.DecodeField(env->FromReflectedField(javaField)); 2266d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 2276d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers // Unbox the value, if necessary. 2282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Object* boxed_value = soa.Decode<mirror::Object*>(javaValue); 2296d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers JValue unboxed_value; 230aaa5edcf2deb1bddcbf5fb27820ad2240ac5b4f2Elliott Hughes if (!UnboxPrimitiveForField(boxed_value, FieldHelper(f).GetType(), unboxed_value, f)) { 2316d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return; 2326d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 2336d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 2346d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers // Check that the receiver is non-null and an instance of the field's declaring class. 2352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Object* o = NULL; 23600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!CheckReceiver(soa, javaObj, f, o)) { 2376d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return; 2386d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 2396d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 2406d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers SetFieldValue(o, f, unboxed_value, true); 2416d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers} 2426d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 2430512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void SetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, char src_descriptor, 2440512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughes const JValue& new_value) { 2451eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers ScopedFastNativeObjectAccess soa(env); 246ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtField* f = soa.DecodeField(env->FromReflectedField(javaField)); 2472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Object* o = NULL; 24800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!CheckReceiver(soa, javaObj, f, o)) { 249ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes return; 25033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 2516d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers FieldHelper fh(f); 2526d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers if (!fh.IsPrimitiveType()) { 25362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowIllegalArgumentException(NULL, StringPrintf("Not a primitive field: %s", 25462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PrettyField(f).c_str()).c_str()); 255c129a6b44193ac3a872f852a69d336e0e7ed8640Jesse Wilson return; 256c129a6b44193ac3a872f852a69d336e0e7ed8640Jesse Wilson } 25733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 25833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes // Widen the value if necessary (and possible). 25933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes JValue wide_value; 2602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* src_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(src_descriptor); 26162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (!ConvertPrimitiveValue(NULL, false, src_type->GetPrimitiveType(), fh.GetTypeAsPrimitiveType(), 2626b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom new_value, wide_value)) { 26333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return; 26433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 26533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 26633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes // Write the value. 26733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes SetFieldValue(o, f, wide_value, false); 26833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 26933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 270f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setBoolean(JNIEnv* env, jobject javaField, jobject javaObj, jboolean z) { 271f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 272f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetZ(z); 273f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'Z', value); 2746d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers} 2756d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 276f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setByte(JNIEnv* env, jobject javaField, jobject javaObj, jbyte b) { 277f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 278f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetB(b); 279f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'B', value); 28033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 28133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 282f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setChar(JNIEnv* env, jobject javaField, jobject javaObj, jchar c) { 283f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 284f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetC(c); 285f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'C', value); 28633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 28733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 288f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setDouble(JNIEnv* env, jobject javaField, jobject javaObj, jdouble d) { 289f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 290f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetD(d); 291f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'D', value); 29233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 29333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 294f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setFloat(JNIEnv* env, jobject javaField, jobject javaObj, jfloat f) { 295f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 296f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetF(f); 297f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'F', value); 29833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 29933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 300f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setInt(JNIEnv* env, jobject javaField, jobject javaObj, jint i) { 301f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 302f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetI(i); 303f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'I', value); 30433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 30533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 306f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setLong(JNIEnv* env, jobject javaField, jobject javaObj, jlong j) { 307f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 308f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetJ(j); 309f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'J', value); 31033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 31133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 312f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setShort(JNIEnv* env, jobject javaField, jobject javaObj, jshort s) { 313f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 314f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetS(s); 315f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'S', value); 31633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 31733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 318f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstromstatic JNINativeMethod gMethods[] = { 3191eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers NATIVE_METHOD(Field, get, "!(Ljava/lang/Object;)Ljava/lang/Object;"), 3201eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers NATIVE_METHOD(Field, getBoolean, "!(Ljava/lang/Object;)Z"), 3211eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers NATIVE_METHOD(Field, getByte, "!(Ljava/lang/Object;)B"), 3221eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers NATIVE_METHOD(Field, getChar, "!(Ljava/lang/Object;)C"), 3231eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers NATIVE_METHOD(Field, getDouble, "!(Ljava/lang/Object;)D"), 3241eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers NATIVE_METHOD(Field, getFloat, "!(Ljava/lang/Object;)F"), 3251eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers NATIVE_METHOD(Field, getInt, "!(Ljava/lang/Object;)I"), 3261eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers NATIVE_METHOD(Field, getLong, "!(Ljava/lang/Object;)J"), 3271eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers NATIVE_METHOD(Field, getShort, "!(Ljava/lang/Object;)S"), 3281eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers NATIVE_METHOD(Field, set, "!(Ljava/lang/Object;Ljava/lang/Object;)V"), 3291eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers NATIVE_METHOD(Field, setBoolean, "!(Ljava/lang/Object;Z)V"), 3301eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers NATIVE_METHOD(Field, setByte, "!(Ljava/lang/Object;B)V"), 3311eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers NATIVE_METHOD(Field, setChar, "!(Ljava/lang/Object;C)V"), 3321eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers NATIVE_METHOD(Field, setDouble, "!(Ljava/lang/Object;D)V"), 3331eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers NATIVE_METHOD(Field, setFloat, "!(Ljava/lang/Object;F)V"), 3341eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers NATIVE_METHOD(Field, setInt, "!(Ljava/lang/Object;I)V"), 3351eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers NATIVE_METHOD(Field, setLong, "!(Ljava/lang/Object;J)V"), 3361eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers NATIVE_METHOD(Field, setShort, "!(Ljava/lang/Object;S)V"), 337f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom}; 338f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom 339f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstromvoid register_java_lang_reflect_Field(JNIEnv* env) { 340eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes REGISTER_NATIVE_METHODS("java/lang/reflect/Field"); 341f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom} 342f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom 343f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom} // namespace art 344