java_lang_reflect_Field.cc revision 62d6c772205b8859f0ebf7ad105402ec4c3e2e01
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" 224f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "mirror/class-inl.h" 232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/field.h" 242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/field-inl.h" 256d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h" 26418d20fc407052d4152157f61e7453359f902383Elliott Hughes#include "reflection.h" 2700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h" 28f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom 29f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstromnamespace art { 30f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom 312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic bool GetFieldValue(const ScopedObjectAccess& soa, mirror::Object* o, mirror::Field* f, 3200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue& value, bool allow_references) 33b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 34f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes DCHECK_EQ(value.GetJ(), 0LL); 3500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(f->GetDeclaringClass(), 3600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers true, true)) { 37923e8b8e936ead33408e111682aa9372e3a7ed43Elliott Hughes return false; 38923e8b8e936ead33408e111682aa9372e3a7ed43Elliott Hughes } 396d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers switch (FieldHelper(f).GetTypeAsPrimitiveType()) { 406b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimBoolean: 41f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetZ(f->GetBoolean(o)); 4233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 436b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimByte: 44f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetB(f->GetByte(o)); 4533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 466b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimChar: 47f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetC(f->GetChar(o)); 4833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 496b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimDouble: 50f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetD(f->GetDouble(o)); 5133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 526b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimFloat: 53f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetF(f->GetFloat(o)); 5433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 556b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimInt: 56f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetI(f->GetInt(o)); 5733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 586b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimLong: 59f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetJ(f->GetLong(o)); 6033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 616b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimShort: 62f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetS(f->GetShort(o)); 6333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 646b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimNot: 6533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes if (allow_references) { 66f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetL(f->GetObject(o)); 6733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return true; 6833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 6933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes // Else break to report an error. 7033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes break; 716b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimVoid: 7233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes // Never okay. 7333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes break; 7433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 7562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowIllegalArgumentException(NULL, 7662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers StringPrintf("Not a primitive field: %s", 7762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PrettyField(f).c_str()).c_str()); 7833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return false; 7933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 8033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 8162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersstatic bool CheckReceiver(const ScopedObjectAccess& soa, jobject j_rcvr, mirror::Field* f, 8262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mirror::Object*& class_or_rcvr) 83b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 84ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes if (f->IsStatic()) { 8562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers class_or_rcvr = f->GetDeclaringClass(); 86ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes return true; 87ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes } 88ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes 8962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers class_or_rcvr = soa.Decode<mirror::Object*>(j_rcvr); 902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* declaringClass = f->GetDeclaringClass(); 9162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (!VerifyObjectInClass(class_or_rcvr, declaringClass)) { 92ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes return false; 93ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes } 94ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes return true; 95ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes} 96ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes 970512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jobject Field_get(JNIEnv* env, jobject javaField, jobject javaObj) { 9800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 992dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Field* f = soa.DecodeField(env->FromReflectedField(javaField)); 1002dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Object* o = NULL; 10100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!CheckReceiver(soa, javaObj, f, o)) { 1026d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return NULL; 1036d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 1046d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 1056d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers // Get the field's value, boxing if necessary. 1061d878f3e1c39162496d7c061f7f6710e414d182bElliott Hughes JValue value; 10700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!GetFieldValue(soa, o, f, value, true)) { 1086d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return NULL; 1096d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 110af6e67a4816d2593586115b89faa659225363246Ian Rogers return 111af6e67a4816d2593586115b89faa659225363246Ian Rogers soa.AddLocalReference<jobject>(BoxPrimitive(FieldHelper(f).GetTypeAsPrimitiveType(), value)); 1126d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers} 1136d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 1140512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic JValue GetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, char dst_descriptor) { 11500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 1162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Field* 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; 1302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* dst_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(dst_descriptor); 13162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (!ConvertPrimitiveValue(NULL, false, FieldHelper(f).GetTypeAsPrimitiveType(), 13262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers dst_type->GetPrimitiveType(), field_value, wide_value)) { 13333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return JValue(); 13433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 13533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return wide_value; 13633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 13733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1380512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jboolean Field_getBoolean(JNIEnv* env, jobject javaField, jobject javaObj) { 139f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'Z').GetZ(); 14033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 14133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1420512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jbyte Field_getByte(JNIEnv* env, jobject javaField, jobject javaObj) { 143f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'B').GetB(); 14433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 14533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1460512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jchar Field_getChar(JNIEnv* env, jobject javaField, jobject javaObj) { 147f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'C').GetC(); 14833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 14933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1500512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jdouble Field_getDouble(JNIEnv* env, jobject javaField, jobject javaObj) { 151f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'D').GetD(); 15233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 15333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1540512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jfloat Field_getFloat(JNIEnv* env, jobject javaField, jobject javaObj) { 155f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'F').GetF(); 15633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 15733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1580512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jint Field_getInt(JNIEnv* env, jobject javaField, jobject javaObj) { 159f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'I').GetI(); 16033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 16133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1620512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jlong Field_getLong(JNIEnv* env, jobject javaField, jobject javaObj) { 163f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'J').GetJ(); 16433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 16533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1660512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jshort Field_getShort(JNIEnv* env, jobject javaField, jobject javaObj) { 167f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return GetPrimitiveField(env, javaField, javaObj, 'S').GetS(); 16833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 16933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 1702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic void SetFieldValue(mirror::Object* o, mirror::Field* f, const JValue& new_value, 1712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers bool allow_references) 172b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 17300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(f->GetDeclaringClass(), 17400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers true, true)) { 175923e8b8e936ead33408e111682aa9372e3a7ed43Elliott Hughes return; 176923e8b8e936ead33408e111682aa9372e3a7ed43Elliott Hughes } 1776d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers switch (FieldHelper(f).GetTypeAsPrimitiveType()) { 1786b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimBoolean: 179f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetBoolean(o, new_value.GetZ()); 180fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1816b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimByte: 182f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetByte(o, new_value.GetB()); 183fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1846b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimChar: 185f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetChar(o, new_value.GetC()); 186fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1876b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimDouble: 188f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetDouble(o, new_value.GetD()); 189fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1906b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimFloat: 191f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetFloat(o, new_value.GetF()); 192fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1936b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimInt: 194f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetInt(o, new_value.GetI()); 195fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1966b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimLong: 197f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetLong(o, new_value.GetJ()); 198fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 1996b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimShort: 200f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetShort(o, new_value.GetS()); 201fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 2026b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimNot: 20333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes if (allow_references) { 204f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes f->SetObject(o, new_value.GetL()); 205fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes break; 20633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 207fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes // Else fall through to report an error. 2086b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimVoid: 20933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes // Never okay. 21062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowIllegalArgumentException(NULL, StringPrintf("Not a primitive field: %s", 21162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PrettyField(f).c_str()).c_str()); 212fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes return; 213fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes } 214fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes 215fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes // Special handling for final fields on SMP systems. 216fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes // We need a store/store barrier here (JMM requirement). 217fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes if (f->IsFinal()) { 218fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes ANDROID_MEMBAR_STORE(); 21933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 22033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 22133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 2220512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void Field_set(JNIEnv* env, jobject javaField, jobject javaObj, jobject javaValue) { 22300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 2242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Field* f = soa.DecodeField(env->FromReflectedField(javaField)); 2256d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 2266d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers // Unbox the value, if necessary. 2272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Object* boxed_value = soa.Decode<mirror::Object*>(javaValue); 2286d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers JValue unboxed_value; 229aaa5edcf2deb1bddcbf5fb27820ad2240ac5b4f2Elliott Hughes if (!UnboxPrimitiveForField(boxed_value, FieldHelper(f).GetType(), unboxed_value, f)) { 2306d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return; 2316d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 2326d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 2336d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers // Check that the receiver is non-null and an instance of the field's declaring class. 2342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Object* o = NULL; 23500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!CheckReceiver(soa, javaObj, f, o)) { 2366d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return; 2376d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 2386d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 2396d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers SetFieldValue(o, f, unboxed_value, true); 2406d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers} 2416d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 2420512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void SetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, char src_descriptor, 2430512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughes const JValue& new_value) { 24400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 2452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Field* f = soa.DecodeField(env->FromReflectedField(javaField)); 2462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Object* o = NULL; 24700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!CheckReceiver(soa, javaObj, f, o)) { 248ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes return; 24933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 2506d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers FieldHelper fh(f); 2516d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers if (!fh.IsPrimitiveType()) { 25262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowIllegalArgumentException(NULL, StringPrintf("Not a primitive field: %s", 25362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PrettyField(f).c_str()).c_str()); 254c129a6b44193ac3a872f852a69d336e0e7ed8640Jesse Wilson return; 255c129a6b44193ac3a872f852a69d336e0e7ed8640Jesse Wilson } 25633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 25733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes // Widen the value if necessary (and possible). 25833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes JValue wide_value; 2592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* src_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(src_descriptor); 26062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (!ConvertPrimitiveValue(NULL, false, src_type->GetPrimitiveType(), fh.GetTypeAsPrimitiveType(), 2616b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom new_value, wide_value)) { 26233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes return; 26333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes } 26433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 26533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes // Write the value. 26633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes SetFieldValue(o, f, wide_value, false); 26733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 26833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 269f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setBoolean(JNIEnv* env, jobject javaField, jobject javaObj, jboolean z) { 270f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 271f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetZ(z); 272f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'Z', value); 2736d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers} 2746d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 275f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setByte(JNIEnv* env, jobject javaField, jobject javaObj, jbyte b) { 276f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 277f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetB(b); 278f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'B', value); 27933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 28033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 281f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setChar(JNIEnv* env, jobject javaField, jobject javaObj, jchar c) { 282f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 283f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetC(c); 284f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'C', value); 28533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 28633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 287f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setDouble(JNIEnv* env, jobject javaField, jobject javaObj, jdouble d) { 288f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 289f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetD(d); 290f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'D', value); 29133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 29233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 293f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setFloat(JNIEnv* env, jobject javaField, jobject javaObj, jfloat f) { 294f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 295f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetF(f); 296f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'F', value); 29733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 29833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 299f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setInt(JNIEnv* env, jobject javaField, jobject javaObj, jint i) { 300f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 301f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetI(i); 302f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'I', value); 30333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 30433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 305f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setLong(JNIEnv* env, jobject javaField, jobject javaObj, jlong j) { 306f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 307f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetJ(j); 308f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'J', value); 30933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 31033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 311f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setShort(JNIEnv* env, jobject javaField, jobject javaObj, jshort s) { 312f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes JValue value; 313f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes value.SetS(s); 314f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes SetPrimitiveField(env, javaField, javaObj, 'S', value); 31533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes} 31633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes 317f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstromstatic JNINativeMethod gMethods[] = { 3186d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, get, "(Ljava/lang/Object;)Ljava/lang/Object;"), 3196d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, getBoolean, "(Ljava/lang/Object;)Z"), 3206d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, getByte, "(Ljava/lang/Object;)B"), 3216d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, getChar, "(Ljava/lang/Object;)C"), 3226d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, getDouble, "(Ljava/lang/Object;)D"), 3236d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, getFloat, "(Ljava/lang/Object;)F"), 3246d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, getInt, "(Ljava/lang/Object;)I"), 3256d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, getLong, "(Ljava/lang/Object;)J"), 3266d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, getShort, "(Ljava/lang/Object;)S"), 3276d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, set, "(Ljava/lang/Object;Ljava/lang/Object;)V"), 3286d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, setBoolean, "(Ljava/lang/Object;Z)V"), 3296d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, setByte, "(Ljava/lang/Object;B)V"), 3306d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, setChar, "(Ljava/lang/Object;C)V"), 3316d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, setDouble, "(Ljava/lang/Object;D)V"), 3326d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, setFloat, "(Ljava/lang/Object;F)V"), 3336d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, setInt, "(Ljava/lang/Object;I)V"), 3346d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, setLong, "(Ljava/lang/Object;J)V"), 3356d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers NATIVE_METHOD(Field, setShort, "(Ljava/lang/Object;S)V"), 336f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom}; 337f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom 338f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstromvoid register_java_lang_reflect_Field(JNIEnv* env) { 339eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes REGISTER_NATIVE_METHODS("java/lang/reflect/Field"); 340f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom} 341f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom 342f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom} // namespace art 343