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