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