java_lang_reflect_Field.cc revision 62f0512bf6d9bc6141358bf22e93afa70dc58b1a
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,
3162f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers                          mirror::ArtField* f, Primitive::Type field_type, bool allow_references,
3262f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers                          JValue* value)
33b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
3462f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  DCHECK_EQ(value->GetJ(), INT64_C(0));
3562f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  DCHECK(f->GetDeclaringClass()->IsInitialized());
3662f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  switch (field_type) {
3762f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    case Primitive::kPrimBoolean:
3862f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      value->SetZ(f->GetBoolean(o));
3933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes      return true;
4062f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    case Primitive::kPrimByte:
4162f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      value->SetB(f->GetByte(o));
4262f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      return true;
4362f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    case Primitive::kPrimChar:
4462f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      value->SetC(f->GetChar(o));
4562f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      return true;
4662f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    case Primitive::kPrimDouble:
4762f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      value->SetD(f->GetDouble(o));
4862f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      return true;
4962f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    case Primitive::kPrimFloat:
5062f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      value->SetF(f->GetFloat(o));
5162f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      return true;
5262f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    case Primitive::kPrimInt:
5362f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      value->SetI(f->GetInt(o));
5462f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      return true;
5562f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    case Primitive::kPrimLong:
5662f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      value->SetJ(f->GetLong(o));
5762f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      return true;
5862f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    case Primitive::kPrimShort:
5962f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      value->SetS(f->GetShort(o));
6062f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      return true;
6162f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    case Primitive::kPrimNot:
6262f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      if (allow_references) {
6362f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers        value->SetL(f->GetObject(o));
6462f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers        return true;
6562f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      }
6662f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      // Else break to report an error.
6762f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      break;
6862f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    case Primitive::kPrimVoid:
6962f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      // Never okay.
7062f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      break;
7133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
7262f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  ThrowIllegalArgumentException(nullptr, StringPrintf("Not a primitive field: %s",
7362f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers                                                      PrettyField(f).c_str()).c_str());
7433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  return false;
7533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
7633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
771eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogersstatic bool CheckReceiver(const ScopedFastNativeObjectAccess& soa, jobject j_rcvr,
7862f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers                          mirror::ArtField* f, mirror::Object** class_or_rcvr)
79b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
8062f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  soa.Self()->AssertThreadSuspensionIsAllowable();
81ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes  if (f->IsStatic()) {
8262f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    SirtRef<mirror::Class> sirt_klass(soa.Self(), f->GetDeclaringClass());
8362f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized(sirt_klass, true, true))) {
8462f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      DCHECK(soa.Self()->IsExceptionPending());
8562f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      *class_or_rcvr = nullptr;
8662f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      return false;
8762f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    }
8862f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    *class_or_rcvr = sirt_klass.get();
89ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes    return true;
90ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes  }
91ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes
9262f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  *class_or_rcvr = soa.Decode<mirror::Object*>(j_rcvr);
932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Class* declaringClass = f->GetDeclaringClass();
9462f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  if (!VerifyObjectIsClass(*class_or_rcvr, declaringClass)) {
9562f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    DCHECK(soa.Self()->IsExceptionPending());
9662f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    *class_or_rcvr = nullptr;
97ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes    return false;
98ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes  }
99ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes  return true;
100ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes}
101ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes
1020512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jobject Field_get(JNIEnv* env, jobject javaField, jobject javaObj) {
1031eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers  ScopedFastNativeObjectAccess soa(env);
10462f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  CHECK(!kMovingFields) << "CheckReceiver may trigger thread suspension for initialization";
10562f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  mirror::ArtField* f = mirror::ArtField::FromReflectedField(soa, javaField);
10662f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  mirror::Object* o = nullptr;
10762f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  if (!CheckReceiver(soa, javaObj, f, &o)) {
10862f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    DCHECK(soa.Self()->IsExceptionPending());
10962f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    return nullptr;
1106d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  }
11162f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  // We now don't expect suspension unless an exception is thrown.
1126d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  // Get the field's value, boxing if necessary.
11362f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  Primitive::Type field_type = FieldHelper(f).GetTypeAsPrimitiveType();
1141d878f3e1c39162496d7c061f7f6710e414d182bElliott Hughes  JValue value;
11562f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  if (!GetFieldValue(soa, o, f, field_type, true, &value)) {
11662f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    DCHECK(soa.Self()->IsExceptionPending());
11762f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    return nullptr;
1186d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  }
11962f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  return soa.AddLocalReference<jobject>(BoxPrimitive(field_type, value));
1206d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers}
1216d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers
122ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromstatic JValue GetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj,
123ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                                char dst_descriptor) {
1241eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers  ScopedFastNativeObjectAccess soa(env);
12562f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  CHECK(!kMovingFields) << "CheckReceiver may trigger thread suspension for initialization";
12662f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  mirror::ArtField* f = mirror::ArtField::FromReflectedField(soa, javaField);
12762f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  mirror::Object* o = nullptr;
12862f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  if (!CheckReceiver(soa, javaObj, f, &o)) {
12962f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    DCHECK(soa.Self()->IsExceptionPending());
130ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes    return JValue();
13133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
13262f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  // We now don't expect suspension unless an exception is thrown.
13333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  // Read the value.
13462f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  Primitive::Type field_type = FieldHelper(f).GetTypeAsPrimitiveType();
1351d878f3e1c39162496d7c061f7f6710e414d182bElliott Hughes  JValue field_value;
13662f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  if (!GetFieldValue(soa, o, f, field_type, false, &field_value)) {
13762f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    DCHECK(soa.Self()->IsExceptionPending());
13833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return JValue();
13933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
14033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
14133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  // Widen it if necessary (and possible).
14233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue wide_value;
14362f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  if (!ConvertPrimitiveValue(NULL, false, field_type, Primitive::GetType(dst_descriptor),
14462f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers                             field_value, wide_value)) {
14562f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    DCHECK(soa.Self()->IsExceptionPending());
14633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return JValue();
14733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
14833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  return wide_value;
14933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
15033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
1510512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jboolean Field_getBoolean(JNIEnv* env, jobject javaField, jobject javaObj) {
152f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  return GetPrimitiveField(env, javaField, javaObj, 'Z').GetZ();
15333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
15433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
1550512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jbyte Field_getByte(JNIEnv* env, jobject javaField, jobject javaObj) {
156f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  return GetPrimitiveField(env, javaField, javaObj, 'B').GetB();
15733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
15833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
1590512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jchar Field_getChar(JNIEnv* env, jobject javaField, jobject javaObj) {
160f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  return GetPrimitiveField(env, javaField, javaObj, 'C').GetC();
16133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
16233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
1630512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jdouble Field_getDouble(JNIEnv* env, jobject javaField, jobject javaObj) {
164f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  return GetPrimitiveField(env, javaField, javaObj, 'D').GetD();
16533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
16633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
1670512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jfloat Field_getFloat(JNIEnv* env, jobject javaField, jobject javaObj) {
168f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  return GetPrimitiveField(env, javaField, javaObj, 'F').GetF();
16933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
17033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
1710512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jint Field_getInt(JNIEnv* env, jobject javaField, jobject javaObj) {
172f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  return GetPrimitiveField(env, javaField, javaObj, 'I').GetI();
17333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
17433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
1750512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jlong Field_getLong(JNIEnv* env, jobject javaField, jobject javaObj) {
176f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  return GetPrimitiveField(env, javaField, javaObj, 'J').GetJ();
17733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
17833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
1790512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jshort Field_getShort(JNIEnv* env, jobject javaField, jobject javaObj) {
180f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  return GetPrimitiveField(env, javaField, javaObj, 'S').GetS();
18133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
18233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
183c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartierstatic void SetFieldValue(ScopedFastNativeObjectAccess& soa, mirror::Object* o,
18462f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers                          mirror::ArtField* f, Primitive::Type field_type, bool allow_references,
18562f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers                          const JValue& new_value)
186b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
18762f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  DCHECK(f->GetDeclaringClass()->IsInitialized());
18862f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  switch (field_type) {
1896b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimBoolean:
190d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    f->SetBoolean<false>(o, new_value.GetZ());
191fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
1926b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimByte:
193d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    f->SetByte<false>(o, new_value.GetB());
194fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
1956b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimChar:
196d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    f->SetChar<false>(o, new_value.GetC());
197fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
1986b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimDouble:
199d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    f->SetDouble<false>(o, new_value.GetD());
200fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
2016b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimFloat:
202d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    f->SetFloat<false>(o, new_value.GetF());
203fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
2046b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimInt:
205d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    f->SetInt<false>(o, new_value.GetI());
206fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
2076b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimLong:
208d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    f->SetLong<false>(o, new_value.GetJ());
209fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
2106b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimShort:
211d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    f->SetShort<false>(o, new_value.GetS());
212fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
2136b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimNot:
21433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    if (allow_references) {
215d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz      f->SetObject<false>(o, new_value.GetL());
216fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes      break;
21733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    }
218fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    // Else fall through to report an error.
2196b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimVoid:
22033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    // Never okay.
22162f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    ThrowIllegalArgumentException(nullptr, StringPrintf("Not a primitive field: %s",
22262f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers                                                        PrettyField(f).c_str()).c_str());
223fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    return;
224fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes  }
22533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
22633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
2270512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void Field_set(JNIEnv* env, jobject javaField, jobject javaObj, jobject javaValue) {
2281eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers  ScopedFastNativeObjectAccess soa(env);
22962f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  CHECK(!kMovingFields) << "CheckReceiver may trigger thread suspension for initialization";
23062f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  mirror::ArtField* f = mirror::ArtField::FromReflectedField(soa, javaField);
23162f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  // Check that the receiver is non-null and an instance of the field's declaring class.
23262f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  mirror::Object* o = nullptr;
23362f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  if (!CheckReceiver(soa, javaObj, f, &o)) {
23462f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    DCHECK(soa.Self()->IsExceptionPending());
23562f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    return;
23662f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  }
23762f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  Primitive::Type field_prim_type;
23862f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  mirror::Class* field_type;
23962f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  {
24062f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    FieldHelper fh(f);
24162f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    const char* field_type_desciptor = fh.GetTypeDescriptor();
24262f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    field_prim_type = Primitive::GetType(field_type_desciptor[0]);
24362f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    if (field_prim_type == Primitive::kPrimNot) {
24462f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      SirtRef<mirror::Object> sirt_obj(soa.Self(), o);
24562f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      // May cause resolution.
24662f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      CHECK(!kMovingFields) << "Resolution may trigger thread suspension";
24762f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      field_type = fh.GetType(true);
24862f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      if (field_type == nullptr) {
24962f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers        DCHECK(soa.Self()->IsExceptionPending());
25062f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers        return;
25162f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      }
25262f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    } else {
25362f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers      field_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(field_type_desciptor[0]);
25462f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    }
25562f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  }
25662f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  // We now don't expect suspension unless an exception is thrown.
2576d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  // Unbox the value, if necessary.
2582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Object* boxed_value = soa.Decode<mirror::Object*>(javaValue);
2596d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  JValue unboxed_value;
26062f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  if (!UnboxPrimitiveForField(boxed_value, field_type, unboxed_value, f)) {
26162f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    DCHECK(soa.Self()->IsExceptionPending());
2626d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers    return;
2636d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  }
26462f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  SetFieldValue(soa, o, f, field_prim_type, true, unboxed_value);
2656d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers}
2666d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers
2670512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void SetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, char src_descriptor,
2680512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughes                              const JValue& new_value) {
2691eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers  ScopedFastNativeObjectAccess soa(env);
27062f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  mirror::ArtField* f = mirror::ArtField::FromReflectedField(soa, javaField);
27162f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  mirror::Object* o = nullptr;
27262f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  if (!CheckReceiver(soa, javaObj, f, &o)) {
273ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes    return;
27433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
27562f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  Primitive::Type field_type = FieldHelper(f).GetTypeAsPrimitiveType();
27662f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  if (UNLIKELY(field_type == Primitive::kPrimNot)) {
27762f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    ThrowIllegalArgumentException(nullptr, StringPrintf("Not a primitive field: %s",
27862f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers                                                        PrettyField(f).c_str()).c_str());
279c129a6b44193ac3a872f852a69d336e0e7ed8640Jesse Wilson    return;
280c129a6b44193ac3a872f852a69d336e0e7ed8640Jesse Wilson  }
28133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
28233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  // Widen the value if necessary (and possible).
28333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue wide_value;
28462f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  if (!ConvertPrimitiveValue(nullptr, false, Primitive::GetType(src_descriptor),
28562f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers                             field_type, new_value, wide_value)) {
28662f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    DCHECK(soa.Self()->IsExceptionPending());
28733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return;
28833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
28933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
29033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  // Write the value.
29162f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  SetFieldValue(soa, o, f, field_type, false, wide_value);
29233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
29333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
294f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setBoolean(JNIEnv* env, jobject javaField, jobject javaObj, jboolean z) {
295f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  JValue value;
296f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  value.SetZ(z);
297f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  SetPrimitiveField(env, javaField, javaObj, 'Z', value);
2986d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers}
2996d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers
300f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setByte(JNIEnv* env, jobject javaField, jobject javaObj, jbyte b) {
301f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  JValue value;
302f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  value.SetB(b);
303f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  SetPrimitiveField(env, javaField, javaObj, 'B', value);
30433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
30533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
306f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setChar(JNIEnv* env, jobject javaField, jobject javaObj, jchar c) {
307f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  JValue value;
308f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  value.SetC(c);
309f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  SetPrimitiveField(env, javaField, javaObj, 'C', value);
31033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
31133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
312f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setDouble(JNIEnv* env, jobject javaField, jobject javaObj, jdouble d) {
313f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  JValue value;
314f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  value.SetD(d);
315f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  SetPrimitiveField(env, javaField, javaObj, 'D', value);
31633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
31733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
318f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setFloat(JNIEnv* env, jobject javaField, jobject javaObj, jfloat f) {
319f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  JValue value;
320f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  value.SetF(f);
321f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  SetPrimitiveField(env, javaField, javaObj, 'F', value);
32233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
32333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
324f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setInt(JNIEnv* env, jobject javaField, jobject javaObj, jint i) {
325f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  JValue value;
326f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  value.SetI(i);
327f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  SetPrimitiveField(env, javaField, javaObj, 'I', value);
32833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
32933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
330f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setLong(JNIEnv* env, jobject javaField, jobject javaObj, jlong j) {
331f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  JValue value;
332f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  value.SetJ(j);
333f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  SetPrimitiveField(env, javaField, javaObj, 'J', value);
33433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
33533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
336f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughesstatic void Field_setShort(JNIEnv* env, jobject javaField, jobject javaObj, jshort s) {
337f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  JValue value;
338f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  value.SetS(s);
339f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes  SetPrimitiveField(env, javaField, javaObj, 'S', value);
34033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
34133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
342f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstromstatic JNINativeMethod gMethods[] = {
3431eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers  NATIVE_METHOD(Field, get,        "!(Ljava/lang/Object;)Ljava/lang/Object;"),
3441eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers  NATIVE_METHOD(Field, getBoolean, "!(Ljava/lang/Object;)Z"),
3451eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers  NATIVE_METHOD(Field, getByte,    "!(Ljava/lang/Object;)B"),
3461eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers  NATIVE_METHOD(Field, getChar,    "!(Ljava/lang/Object;)C"),
3471eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers  NATIVE_METHOD(Field, getDouble,  "!(Ljava/lang/Object;)D"),
3481eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers  NATIVE_METHOD(Field, getFloat,   "!(Ljava/lang/Object;)F"),
3491eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers  NATIVE_METHOD(Field, getInt,     "!(Ljava/lang/Object;)I"),
3501eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers  NATIVE_METHOD(Field, getLong,    "!(Ljava/lang/Object;)J"),
3511eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers  NATIVE_METHOD(Field, getShort,   "!(Ljava/lang/Object;)S"),
3521eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers  NATIVE_METHOD(Field, set,        "!(Ljava/lang/Object;Ljava/lang/Object;)V"),
3531eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers  NATIVE_METHOD(Field, setBoolean, "!(Ljava/lang/Object;Z)V"),
3541eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers  NATIVE_METHOD(Field, setByte,    "!(Ljava/lang/Object;B)V"),
3551eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers  NATIVE_METHOD(Field, setChar,    "!(Ljava/lang/Object;C)V"),
3561eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers  NATIVE_METHOD(Field, setDouble,  "!(Ljava/lang/Object;D)V"),
3571eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers  NATIVE_METHOD(Field, setFloat,   "!(Ljava/lang/Object;F)V"),
3581eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers  NATIVE_METHOD(Field, setInt,     "!(Ljava/lang/Object;I)V"),
3591eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers  NATIVE_METHOD(Field, setLong,    "!(Ljava/lang/Object;J)V"),
3601eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers  NATIVE_METHOD(Field, setShort,   "!(Ljava/lang/Object;S)V"),
361f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom};
362f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom
363f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstromvoid register_java_lang_reflect_Field(JNIEnv* env) {
364eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes  REGISTER_NATIVE_METHODS("java/lang/reflect/Field");
365f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom}
366f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom
367f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom}  // namespace art
368