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