java_lang_reflect_Field.cc revision 2dd0e2cea360bc9206eb88ecc40d259e796c239d
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"
19eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes#include "jni_internal.h"
202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/field.h"
212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/field-inl.h"
226d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h"
23418d20fc407052d4152157f61e7453359f902383Elliott Hughes#include "reflection.h"
2400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h"
25f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom
26f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstromnamespace art {
27f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom
282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic bool GetFieldValue(const ScopedObjectAccess& soa, mirror::Object* o, mirror::Field* f,
2900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                          JValue& value, bool allow_references)
30b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
31f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  DCHECK_EQ(value.GetJ(), 0LL);
3200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(f->GetDeclaringClass(),
3300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                                               true, true)) {
34923e8b8e936ead33408e111682aa9372e3a7ed43Elliott Hughes    return false;
35923e8b8e936ead33408e111682aa9372e3a7ed43Elliott Hughes  }
366d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  switch (FieldHelper(f).GetTypeAsPrimitiveType()) {
376b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimBoolean:
38f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    value.SetZ(f->GetBoolean(o));
3933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return true;
406b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimByte:
41f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    value.SetB(f->GetByte(o));
4233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return true;
436b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimChar:
44f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    value.SetC(f->GetChar(o));
4533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return true;
466b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimDouble:
47f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    value.SetD(f->GetDouble(o));
4833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return true;
496b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimFloat:
50f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    value.SetF(f->GetFloat(o));
5133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return true;
526b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimInt:
53f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    value.SetI(f->GetInt(o));
5433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return true;
556b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimLong:
56f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    value.SetJ(f->GetLong(o));
5733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return true;
586b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimShort:
59f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    value.SetS(f->GetShort(o));
6033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return true;
616b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimNot:
6233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    if (allow_references) {
63f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes      value.SetL(f->GetObject(o));
6433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes      return true;
6533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    }
6633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    // Else break to report an error.
6733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    break;
686b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimVoid:
6933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    // Never okay.
7033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    break;
7133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
7200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  soa.Self()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
7333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes      "Not a primitive field: %s", PrettyField(f).c_str());
7433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  return false;
7533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
7633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
772dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic bool CheckReceiver(const ScopedObjectAccess& soa, jobject javaObj, mirror::Field* f,
782dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                          mirror::Object*& o)
79b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
80ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes  if (f->IsStatic()) {
812fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers    o = f->GetDeclaringClass();
82ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes    return true;
83ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes  }
84ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes
852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  o = soa.Decode<mirror::Object*>(javaObj);
862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Class* declaringClass = f->GetDeclaringClass();
87eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes  if (!VerifyObjectInClass(o, declaringClass)) {
88ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes    return false;
89ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes  }
90ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes  return true;
91ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes}
92ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes
930512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jobject Field_get(JNIEnv* env, jobject javaField, jobject javaObj) {
9400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(env);
952dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Field* f = soa.DecodeField(env->FromReflectedField(javaField));
962dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Object* o = NULL;
9700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (!CheckReceiver(soa, javaObj, f, o)) {
986d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers    return NULL;
996d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  }
1006d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers
1016d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  // Get the field's value, boxing if necessary.
1021d878f3e1c39162496d7c061f7f6710e414d182bElliott Hughes  JValue value;
10300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (!GetFieldValue(soa, o, f, value, true)) {
1046d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers    return NULL;
1056d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  }
106af6e67a4816d2593586115b89faa659225363246Ian Rogers  return
107af6e67a4816d2593586115b89faa659225363246Ian Rogers      soa.AddLocalReference<jobject>(BoxPrimitive(FieldHelper(f).GetTypeAsPrimitiveType(), value));
1086d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers}
1096d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers
1100512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic JValue GetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, char dst_descriptor) {
11100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(env);
1122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Field* f = soa.DecodeField(env->FromReflectedField(javaField));
1132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Object* o = NULL;
11400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (!CheckReceiver(soa, javaObj, f, o)) {
115ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes    return JValue();
11633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
11733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
11833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  // Read the value.
1191d878f3e1c39162496d7c061f7f6710e414d182bElliott Hughes  JValue field_value;
12000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (!GetFieldValue(soa, o, f, field_value, false)) {
12133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return JValue();
12233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
12333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
12433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  // Widen it if necessary (and possible).
12533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue wide_value;
1262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Class* dst_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(dst_descriptor);
1276d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  if (!ConvertPrimitiveValue(FieldHelper(f).GetTypeAsPrimitiveType(), dst_type->GetPrimitiveType(),
1286b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom                             field_value, wide_value)) {
12933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return JValue();
13033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
13133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  return wide_value;
13233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
13333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
1340512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jboolean Field_getBoolean(JNIEnv* env, jobject javaField, jobject javaObj) {
135f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  return GetPrimitiveField(env, javaField, javaObj, 'Z').GetZ();
13633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
13733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
1380512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jbyte Field_getByte(JNIEnv* env, jobject javaField, jobject javaObj) {
139f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  return GetPrimitiveField(env, javaField, javaObj, 'B').GetB();
14033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
14133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
1420512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jchar Field_getChar(JNIEnv* env, jobject javaField, jobject javaObj) {
143f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  return GetPrimitiveField(env, javaField, javaObj, 'C').GetC();
14433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
14533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
1460512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jdouble Field_getDouble(JNIEnv* env, jobject javaField, jobject javaObj) {
147f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  return GetPrimitiveField(env, javaField, javaObj, 'D').GetD();
14833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
14933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
1500512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jfloat Field_getFloat(JNIEnv* env, jobject javaField, jobject javaObj) {
151f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  return GetPrimitiveField(env, javaField, javaObj, 'F').GetF();
15233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
15333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
1540512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jint Field_getInt(JNIEnv* env, jobject javaField, jobject javaObj) {
155f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  return GetPrimitiveField(env, javaField, javaObj, 'I').GetI();
15633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
15733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
1580512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jlong Field_getLong(JNIEnv* env, jobject javaField, jobject javaObj) {
159f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  return GetPrimitiveField(env, javaField, javaObj, 'J').GetJ();
16033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
16133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
1620512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jshort Field_getShort(JNIEnv* env, jobject javaField, jobject javaObj) {
163f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  return GetPrimitiveField(env, javaField, javaObj, 'S').GetS();
16433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
16533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
1662dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic void SetFieldValue(mirror::Object* o, mirror::Field* f, const JValue& new_value,
1672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                          bool allow_references)
168b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
16900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(f->GetDeclaringClass(),
17000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                                               true, true)) {
171923e8b8e936ead33408e111682aa9372e3a7ed43Elliott Hughes    return;
172923e8b8e936ead33408e111682aa9372e3a7ed43Elliott Hughes  }
1736d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  switch (FieldHelper(f).GetTypeAsPrimitiveType()) {
1746b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimBoolean:
175f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    f->SetBoolean(o, new_value.GetZ());
176fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
1776b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimByte:
178f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    f->SetByte(o, new_value.GetB());
179fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
1806b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimChar:
181f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    f->SetChar(o, new_value.GetC());
182fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
1836b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimDouble:
184f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    f->SetDouble(o, new_value.GetD());
185fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
1866b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimFloat:
187f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    f->SetFloat(o, new_value.GetF());
188fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
1896b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimInt:
190f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    f->SetInt(o, new_value.GetI());
191fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
1926b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimLong:
193f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    f->SetLong(o, new_value.GetJ());
194fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
1956b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimShort:
196f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    f->SetShort(o, new_value.GetS());
197fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
1986b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimNot:
19933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    if (allow_references) {
200f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes      f->SetObject(o, new_value.GetL());
201fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes      break;
20233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    }
203fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    // Else fall through to report an error.
2046b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimVoid:
20533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    // Never okay.
2065cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes    Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
207fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes        "Not a primitive field: %s", PrettyField(f).c_str());
208fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    return;
209fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes  }
210fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes
211fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes  // Special handling for final fields on SMP systems.
212fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes  // We need a store/store barrier here (JMM requirement).
213fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes  if (f->IsFinal()) {
214fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    ANDROID_MEMBAR_STORE();
21533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
21633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
21733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
2180512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void Field_set(JNIEnv* env, jobject javaField, jobject javaObj, jobject javaValue) {
21900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(env);
2202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Field* f = soa.DecodeField(env->FromReflectedField(javaField));
2216d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers
2226d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  // Unbox the value, if necessary.
2232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Object* boxed_value = soa.Decode<mirror::Object*>(javaValue);
2246d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  JValue unboxed_value;
225aaa5edcf2deb1bddcbf5fb27820ad2240ac5b4f2Elliott Hughes  if (!UnboxPrimitiveForField(boxed_value, FieldHelper(f).GetType(), unboxed_value, f)) {
2266d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers    return;
2276d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  }
2286d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers
2296d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  // Check that the receiver is non-null and an instance of the field's declaring class.
2302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Object* o = NULL;
23100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (!CheckReceiver(soa, javaObj, f, o)) {
2326d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers    return;
2336d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  }
2346d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers
2356d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  SetFieldValue(o, f, unboxed_value, true);
2366d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers}
2376d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers
2380512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void SetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, char src_descriptor,
2390512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughes                              const JValue& new_value) {
24000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(env);
2412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Field* f = soa.DecodeField(env->FromReflectedField(javaField));
2422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Object* o = NULL;
24300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (!CheckReceiver(soa, javaObj, f, o)) {
244ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes    return;
24533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
2466d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  FieldHelper fh(f);
2476d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  if (!fh.IsPrimitiveType()) {
24800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    soa.Self()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
249c129a6b44193ac3a872f852a69d336e0e7ed8640Jesse Wilson        "Not a primitive field: %s", PrettyField(f).c_str());
250c129a6b44193ac3a872f852a69d336e0e7ed8640Jesse Wilson    return;
251c129a6b44193ac3a872f852a69d336e0e7ed8640Jesse Wilson  }
25233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
25333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  // Widen the value if necessary (and possible).
25433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue wide_value;
2552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Class* src_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(src_descriptor);
2566d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  if (!ConvertPrimitiveValue(src_type->GetPrimitiveType(), fh.GetTypeAsPrimitiveType(),
2576b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom                             new_value, wide_value)) {
25833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return;
25933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
26033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
26133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  // Write the value.
26233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  SetFieldValue(o, f, wide_value, false);
26333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
26433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
265f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setBoolean(JNIEnv* env, jobject javaField, jobject javaObj, jboolean z) {
266f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  JValue value;
267f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  value.SetZ(z);
268f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  SetPrimitiveField(env, javaField, javaObj, 'Z', value);
2696d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers}
2706d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers
271f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setByte(JNIEnv* env, jobject javaField, jobject javaObj, jbyte b) {
272f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  JValue value;
273f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  value.SetB(b);
274f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  SetPrimitiveField(env, javaField, javaObj, 'B', value);
27533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
27633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
277f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setChar(JNIEnv* env, jobject javaField, jobject javaObj, jchar c) {
278f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  JValue value;
279f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  value.SetC(c);
280f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  SetPrimitiveField(env, javaField, javaObj, 'C', value);
28133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
28233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
283f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setDouble(JNIEnv* env, jobject javaField, jobject javaObj, jdouble d) {
284f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  JValue value;
285f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  value.SetD(d);
286f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  SetPrimitiveField(env, javaField, javaObj, 'D', value);
28733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
28833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
289f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setFloat(JNIEnv* env, jobject javaField, jobject javaObj, jfloat f) {
290f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  JValue value;
291f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  value.SetF(f);
292f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  SetPrimitiveField(env, javaField, javaObj, 'F', value);
29333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
29433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
295f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setInt(JNIEnv* env, jobject javaField, jobject javaObj, jint i) {
296f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  JValue value;
297f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  value.SetI(i);
298f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  SetPrimitiveField(env, javaField, javaObj, 'I', value);
29933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
30033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
301f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setLong(JNIEnv* env, jobject javaField, jobject javaObj, jlong j) {
302f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  JValue value;
303f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  value.SetJ(j);
304f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  SetPrimitiveField(env, javaField, javaObj, 'J', value);
30533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
30633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
307f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setShort(JNIEnv* env, jobject javaField, jobject javaObj, jshort s) {
308f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  JValue value;
309f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  value.SetS(s);
310f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  SetPrimitiveField(env, javaField, javaObj, 'S', value);
31133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
31233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
313f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstromstatic JNINativeMethod gMethods[] = {
3146d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  NATIVE_METHOD(Field, get,        "(Ljava/lang/Object;)Ljava/lang/Object;"),
3156d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  NATIVE_METHOD(Field, getBoolean, "(Ljava/lang/Object;)Z"),
3166d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  NATIVE_METHOD(Field, getByte,    "(Ljava/lang/Object;)B"),
3176d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  NATIVE_METHOD(Field, getChar,    "(Ljava/lang/Object;)C"),
3186d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  NATIVE_METHOD(Field, getDouble,  "(Ljava/lang/Object;)D"),
3196d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  NATIVE_METHOD(Field, getFloat,   "(Ljava/lang/Object;)F"),
3206d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  NATIVE_METHOD(Field, getInt,     "(Ljava/lang/Object;)I"),
3216d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  NATIVE_METHOD(Field, getLong,    "(Ljava/lang/Object;)J"),
3226d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  NATIVE_METHOD(Field, getShort,   "(Ljava/lang/Object;)S"),
3236d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  NATIVE_METHOD(Field, set,        "(Ljava/lang/Object;Ljava/lang/Object;)V"),
3246d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  NATIVE_METHOD(Field, setBoolean, "(Ljava/lang/Object;Z)V"),
3256d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  NATIVE_METHOD(Field, setByte,    "(Ljava/lang/Object;B)V"),
3266d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  NATIVE_METHOD(Field, setChar,    "(Ljava/lang/Object;C)V"),
3276d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  NATIVE_METHOD(Field, setDouble,  "(Ljava/lang/Object;D)V"),
3286d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  NATIVE_METHOD(Field, setFloat,   "(Ljava/lang/Object;F)V"),
3296d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  NATIVE_METHOD(Field, setInt,     "(Ljava/lang/Object;I)V"),
3306d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  NATIVE_METHOD(Field, setLong,    "(Ljava/lang/Object;J)V"),
3316d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  NATIVE_METHOD(Field, setShort,   "(Ljava/lang/Object;S)V"),
332f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom};
333f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom
334f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstromvoid register_java_lang_reflect_Field(JNIEnv* env) {
335eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes  REGISTER_NATIVE_METHODS("java/lang/reflect/Field");
336f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom}
337f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom
338f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom}  // namespace art
339