java_lang_reflect_Field.cc revision fe6207f7d3a38e021f81f7c3d25f085883e4cf43
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 "jni_internal.h"
18f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom#include "class_linker.h"
19f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom#include "object.h"
20418d20fc407052d4152157f61e7453359f902383Elliott Hughes#include "reflection.h"
21f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom
22f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom#include "JniConstants.h" // Last to avoid problems with LOG redefinition.
23f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom
24f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstromnamespace art {
25f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom
26f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstromnamespace {
27f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom
28f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstromjint Field_getFieldModifiers(JNIEnv* env, jobject jfield, jclass javaDeclaringClass, jint slot) {
29f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom  return Decode<Object*>(env, jfield)->AsField()->GetAccessFlags() & kAccFieldFlagsMask;
30f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom}
31f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom
3233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughesbool GetFieldValue(Object* o, Field* f, JValue& value, bool allow_references) {
3333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  switch (f->GetType()->GetPrimitiveType()) {
3433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  case Class::kPrimBoolean:
3533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    value.z = f->GetBoolean(o);
3633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return true;
3733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  case Class::kPrimByte:
3833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    value.b = f->GetByte(o);
3933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return true;
4033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  case Class::kPrimChar:
4133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    value.c = f->GetChar(o);
4233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return true;
4333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  case Class::kPrimDouble:
4433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    value.d = f->GetDouble(o);
4533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return true;
4633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  case Class::kPrimFloat:
4733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    value.f = f->GetFloat(o);
4833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return true;
4933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  case Class::kPrimInt:
5033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    value.i = f->GetInt(o);
5133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return true;
5233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  case Class::kPrimLong:
5333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    value.j = f->GetLong(o);
5433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return true;
5533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  case Class::kPrimShort:
5633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    value.s = f->GetShort(o);
5733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return true;
5833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  case Class::kPrimNot:
5933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    if (allow_references) {
6033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes      value.l = f->GetObject(o);
6133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes      return true;
6233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    }
6333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    // Else break to report an error.
6433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    break;
6533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  case Class::kPrimVoid:
6633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    // Never okay.
6733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    break;
6833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
6933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  Thread::Current()->ThrowNewException("Ljava/lang/IllegalArgumentException;",
7033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes      "Not a primitive field: %s", PrettyField(f).c_str());
7133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  return false;
7233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
7333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
7433203b59aa5f27bac0433bdb640f1f1e911186ebElliott HughesJValue GetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jchar targetDescriptor) {
75418d20fc407052d4152157f61e7453359f902383Elliott Hughes  Field* f = DecodeField(env->FromReflectedField(javaField));
7633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
7733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  // Check that the receiver is non-null and an instance of the field's declaring class.
7833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  Object* o = Decode<Object*>(env, javaObj);
7933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  bool isStatic = (javaObj == NULL);
8033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  if (!isStatic) {
8133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    Class* declaringClass = Decode<Class*>(env, javaDeclaringClass);
8233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    if (!VerifyObjectInClass(env, o, declaringClass)) {
8333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes      return JValue();
8433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    }
8533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
8633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
8733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  // Read the value.
8833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue field_value;
8933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  if (!GetFieldValue(o, f, field_value, false)) {
9033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return JValue();
9133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
9233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
9333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  // Widen it if necessary (and possible).
9433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue wide_value;
9533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  Class* targetType = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(targetDescriptor);
9633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  if (!ConvertPrimitiveValue(f->GetType(), targetType, field_value, wide_value)) {
9733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return JValue();
9833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
9933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  return wide_value;
10033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
10133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
10233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughesjbyte Field_getBField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar targetDescriptor) {
10333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  return GetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, targetDescriptor).b;
10433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
10533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
10633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughesjchar Field_getCField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar targetDescriptor) {
10733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  return GetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, targetDescriptor).c;
10833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
10933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
11033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughesjdouble Field_getDField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar targetDescriptor) {
11133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  return GetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, targetDescriptor).d;
11233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
11333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
11433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughesjfloat Field_getFField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar targetDescriptor) {
11533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  return GetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, targetDescriptor).f;
11633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
11733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
11833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughesjint Field_getIField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar targetDescriptor) {
11933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  return GetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, targetDescriptor).i;
12033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
12133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
12233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughesjlong Field_getJField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar targetDescriptor) {
12333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  return GetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, targetDescriptor).j;
12433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
12533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
12633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughesjshort Field_getSField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar targetDescriptor) {
12733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  return GetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, targetDescriptor).s;
12833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
12933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
13033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughesjboolean Field_getZField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar targetDescriptor) {
13133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  return GetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, targetDescriptor).z;
13233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
13333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
13433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughesvoid SetFieldValue(Object* o, Field* f, const JValue& new_value, bool allow_references) {
13533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  switch (f->GetType()->GetPrimitiveType()) {
13633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  case Class::kPrimBoolean:
13733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    f->SetBoolean(o, new_value.z);
138fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
13933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  case Class::kPrimByte:
14033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    f->SetByte(o, new_value.b);
141fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
14233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  case Class::kPrimChar:
14333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    f->SetChar(o, new_value.c);
144fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
14533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  case Class::kPrimDouble:
14633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    f->SetDouble(o, new_value.d);
147fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
14833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  case Class::kPrimFloat:
14933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    f->SetFloat(o, new_value.f);
150fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
15133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  case Class::kPrimInt:
15233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    f->SetInt(o, new_value.i);
153fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
15433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  case Class::kPrimLong:
15533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    f->SetLong(o, new_value.j);
156fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
15733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  case Class::kPrimShort:
15833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    f->SetShort(o, new_value.s);
159fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
16033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  case Class::kPrimNot:
16133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    if (allow_references) {
16233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes      f->SetObject(o, new_value.l);
163fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes      break;
16433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    }
165fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    // Else fall through to report an error.
16633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  case Class::kPrimVoid:
16733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    // Never okay.
168fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    Thread::Current()->ThrowNewException("Ljava/lang/IllegalArgumentException;",
169fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes        "Not a primitive field: %s", PrettyField(f).c_str());
170fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    return;
171fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes  }
172fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes
173fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes  // Special handling for final fields on SMP systems.
174fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes  // We need a store/store barrier here (JMM requirement).
175fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes  if (f->IsFinal()) {
176fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    ANDROID_MEMBAR_STORE();
17733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
17833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
17933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
18033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughesvoid SetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jchar targetDescriptor, const JValue& new_value) {
181418d20fc407052d4152157f61e7453359f902383Elliott Hughes  Field* f = DecodeField(env->FromReflectedField(javaField));
18233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
18333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  // Check that the receiver is non-null and an instance of the field's declaring class.
18433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  Object* o = Decode<Object*>(env, javaObj);
18533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  bool isStatic = (javaObj == NULL);
18633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  if (!isStatic) {
18733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    Class* declaringClass = Decode<Class*>(env, javaDeclaringClass);
18833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    if (!VerifyObjectInClass(env, o, declaringClass)) {
18933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes      return;
19033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    }
19133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
19233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
19333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  // Widen the value if necessary (and possible).
19433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue wide_value;
19533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  Class* targetType = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(targetDescriptor);
19633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  if (!ConvertPrimitiveValue(f->GetType(), targetType, new_value, wide_value)) {
19733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return;
19833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
19933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
20033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  // Write the value.
20133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  SetFieldValue(o, f, wide_value, false);
20233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
20333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
20433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughesvoid Field_setBField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar targetDescriptor, jbyte value) {
20533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue v = { 0 };
20633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  v.b = value;
20733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  SetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, targetDescriptor, v);
20833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
20933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
21033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughesvoid Field_setCField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar targetDescriptor, jchar value) {
21133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue v = { 0 };
21233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  v.c = value;
21333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  SetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, targetDescriptor, v);
21433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
21533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
21633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughesvoid Field_setDField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar targetDescriptor, jdouble value) {
21733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue v = { 0 };
21833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  v.d = value;
21933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  SetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, targetDescriptor, v);
22033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
22133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
22233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughesvoid Field_setFField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar targetDescriptor, jfloat value) {
22333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue v = { 0 };
22433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  v.f = value;
22533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  SetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, targetDescriptor, v);
22633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
22733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
22833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughesvoid Field_setIField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar targetDescriptor, jint value) {
22933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue v = { 0 };
23033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  v.i = value;
23133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  SetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, targetDescriptor, v);
23233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
23333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
23433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughesvoid Field_setJField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar targetDescriptor, jlong value) {
23533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue v = { 0 };
23633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  v.j = value;
23733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  SetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, targetDescriptor, v);
23833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
23933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
24033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughesvoid Field_setSField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar targetDescriptor, jshort value) {
24133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue v = { 0 };
24233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  v.s = value;
24333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  SetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, targetDescriptor, v);
24433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
24533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
24633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughesvoid Field_setZField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar targetDescriptor, jboolean value) {
24733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue v = { 0 };
24833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  v.z = value;
24933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  SetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, targetDescriptor, v);
25033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
25133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
25233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughesvoid Field_setField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jobject javaValue) {
253418d20fc407052d4152157f61e7453359f902383Elliott Hughes  Field* f = DecodeField(env->FromReflectedField(javaField));
25433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
25533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  // Unbox the value, if necessary.
25633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  Object* boxed_value = Decode<Object*>(env, javaValue);
25733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue unboxed_value;
25833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  if (!UnboxPrimitive(env, boxed_value, f->GetType(), unboxed_value)) {
25933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return;
26033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
26133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
26233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  // Check that the receiver is non-null and an instance of the field's declaring class.
26333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  Object* o = Decode<Object*>(env, javaObj);
26433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  bool isStatic = (javaObj == NULL);
26533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  if (!isStatic) {
26633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    Class* declaringClass = Decode<Class*>(env, javaDeclaringClass);
26733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    if (!VerifyObjectInClass(env, o, declaringClass)) {
26833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes      return;
26933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    }
27033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
27133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
27233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  SetFieldValue(o, f, unboxed_value, true);
27333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
27433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
27533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughesjobject Field_getField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean) {
276418d20fc407052d4152157f61e7453359f902383Elliott Hughes  Field* f = DecodeField(env->FromReflectedField(javaField));
27733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
27833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  // Check that the receiver is non-null and an instance of the field's declaring class.
27933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  Object* o = Decode<Object*>(env, javaObj);
28033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  bool isStatic = (javaObj == NULL);
28133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  if (!isStatic) {
28233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    Class* declaringClass = Decode<Class*>(env, javaDeclaringClass);
28333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    if (!VerifyObjectInClass(env, o, declaringClass)) {
28433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes      return NULL;
28533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    }
28633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
28733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
28833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  // Get the field's value, boxing if necessary.
28933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue value;
29033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  if (!GetFieldValue(o, f, value, true)) {
29133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return NULL;
29233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
29333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  BoxPrimitive(env, f->GetType(), value);
29433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
29533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  return AddLocalReference<jobject>(env, value.l);
29633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
29733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
298f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstromstatic JNINativeMethod gMethods[] = {
29933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, getFieldModifiers, "(Ljava/lang/Class;I)I"),
30033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
30133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, getBField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)B"),
30233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, getCField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)C"),
30333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, getDField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)D"),
30433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, getFField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)F"),
30533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, getField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZ)Ljava/lang/Object;"),
30633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, getIField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)I"),
30733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, getJField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)J"),
30833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, getSField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)S"),
30933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, getZField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)Z"),
31033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, setBField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCB)V"),
31133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, setCField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCC)V"),
31233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, setDField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCD)V"),
31333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, setFField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCF)V"),
31433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, setField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZLjava/lang/Object;)V"),
31533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, setIField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCI)V"),
31633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, setJField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCJ)V"),
31733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, setSField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCS)V"),
31833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, setZField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCZ)V"),
319f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom};
320f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom
321f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom}  // namespace
322f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom
323f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstromvoid register_java_lang_reflect_Field(JNIEnv* env) {
324418d20fc407052d4152157f61e7453359f902383Elliott Hughes  InitBoxingMethods(env); // TODO: move to Runtime?
325f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom  jniRegisterNativeMethods(env, "java/lang/reflect/Field", gMethods, NELEM(gMethods));
326f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom}
327f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom
328f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom}  // namespace art
329