java_lang_reflect_Field.cc revision 6b4ef025af12b158d117fc80fc79acf620f411a0
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) {
29582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughes  return Decode<Object*>(env, jfield)->AsField()->GetAccessFlags() & kAccJavaFlagsMask;
30f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom}
31f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom
3233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughesbool GetFieldValue(Object* o, Field* f, JValue& value, bool allow_references) {
336b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  switch (f->GetPrimitiveType()) {
346b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimBoolean:
3533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    value.z = f->GetBoolean(o);
3633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return true;
376b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimByte:
3833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    value.b = f->GetByte(o);
3933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return true;
406b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimChar:
4133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    value.c = f->GetChar(o);
4233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return true;
436b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimDouble:
4433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    value.d = f->GetDouble(o);
4533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return true;
466b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimFloat:
4733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    value.f = f->GetFloat(o);
4833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return true;
496b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimInt:
5033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    value.i = f->GetInt(o);
5133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return true;
526b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimLong:
5333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    value.j = f->GetLong(o);
5433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return true;
556b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimShort:
5633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    value.s = f->GetShort(o);
5733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return true;
586b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::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;
656b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimVoid:
6633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    // Never okay.
6733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    break;
6833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
695cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
7033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes      "Not a primitive field: %s", PrettyField(f).c_str());
7133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  return false;
7233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
7333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
74ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughesbool CheckReceiver(JNIEnv* env, jobject javaObj, jclass javaDeclaringClass, Field* f, Object*& o) {
75ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes  if (f->IsStatic()) {
76ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes    o = NULL;
77ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes    return true;
78ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes  }
79ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes
80ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes  o = Decode<Object*>(env, javaObj);
81ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes  Class* declaringClass = Decode<Class*>(env, javaDeclaringClass);
82ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes  if (!VerifyObjectInClass(env, o, declaringClass)) {
83ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes    return false;
84ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes  }
85ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes  return true;
86ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes}
87ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes
88582a7d16bb0db323d8bd730beb61578aa3765f43Elliott HughesJValue GetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jchar dst_descriptor) {
89418d20fc407052d4152157f61e7453359f902383Elliott Hughes  Field* f = DecodeField(env->FromReflectedField(javaField));
90ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes  Object* o = NULL;
91ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes  if (!CheckReceiver(env, javaObj, javaDeclaringClass, f, o)) {
92ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes    return JValue();
9333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
9433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
9533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  // Read the value.
9633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue field_value;
9733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  if (!GetFieldValue(o, f, field_value, false)) {
9833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return JValue();
9933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
10033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
10133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  // Widen it if necessary (and possible).
10233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue wide_value;
103582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughes  Class* dst_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(dst_descriptor);
1046b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  if (!ConvertPrimitiveValue(f->GetPrimitiveType(), dst_type->GetPrimitiveType(),
1056b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom                             field_value, wide_value)) {
10633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return JValue();
10733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
10833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  return wide_value;
10933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
11033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
111582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughesjbyte Field_getBField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar dst_descriptor) {
112582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughes  return GetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, dst_descriptor).b;
11333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
11433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
115582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughesjchar Field_getCField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar dst_descriptor) {
116582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughes  return GetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, dst_descriptor).c;
11733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
11833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
119582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughesjdouble Field_getDField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar dst_descriptor) {
120582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughes  return GetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, dst_descriptor).d;
12133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
12233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
123582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughesjfloat Field_getFField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar dst_descriptor) {
124582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughes  return GetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, dst_descriptor).f;
12533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
12633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
127582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughesjint Field_getIField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar dst_descriptor) {
128582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughes  return GetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, dst_descriptor).i;
12933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
13033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
131582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughesjlong Field_getJField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar dst_descriptor) {
132582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughes  return GetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, dst_descriptor).j;
13333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
13433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
135582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughesjshort Field_getSField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar dst_descriptor) {
136582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughes  return GetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, dst_descriptor).s;
13733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
13833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
139582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughesjboolean Field_getZField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar dst_descriptor) {
140582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughes  return GetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, dst_descriptor).z;
14133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
14233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
14333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughesvoid SetFieldValue(Object* o, Field* f, const JValue& new_value, bool allow_references) {
1446b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  switch (f->GetPrimitiveType()) {
1456b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimBoolean:
14633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    f->SetBoolean(o, new_value.z);
147fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
1486b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimByte:
14933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    f->SetByte(o, new_value.b);
150fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
1516b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimChar:
15233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    f->SetChar(o, new_value.c);
153fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
1546b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimDouble:
15533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    f->SetDouble(o, new_value.d);
156fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
1576b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimFloat:
15833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    f->SetFloat(o, new_value.f);
159fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
1606b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimInt:
16133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    f->SetInt(o, new_value.i);
162fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
1636b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimLong:
16433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    f->SetLong(o, new_value.j);
165fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
1666b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimShort:
16733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    f->SetShort(o, new_value.s);
168fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    break;
1696b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimNot:
17033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    if (allow_references) {
17133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes      f->SetObject(o, new_value.l);
172fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes      break;
17333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    }
174fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    // Else fall through to report an error.
1756b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  case Primitive::kPrimVoid:
17633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    // Never okay.
1775cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes    Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
178fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes        "Not a primitive field: %s", PrettyField(f).c_str());
179fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    return;
180fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes  }
181fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes
182fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes  // Special handling for final fields on SMP systems.
183fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes  // We need a store/store barrier here (JMM requirement).
184fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes  if (f->IsFinal()) {
185fe6207f7d3a38e021f81f7c3d25f085883e4cf43Elliott Hughes    ANDROID_MEMBAR_STORE();
18633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
18733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
18833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
189582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughesvoid SetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jchar src_descriptor, const JValue& new_value) {
190418d20fc407052d4152157f61e7453359f902383Elliott Hughes  Field* f = DecodeField(env->FromReflectedField(javaField));
191ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes  Object* o = NULL;
192ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes  if (!CheckReceiver(env, javaObj, javaDeclaringClass, f, o)) {
193ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes    return;
19433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
19533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
19633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  // Widen the value if necessary (and possible).
19733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue wide_value;
198582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughes  Class* src_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(src_descriptor);
1996b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  if (!ConvertPrimitiveValue(src_type->GetPrimitiveType(), f->GetPrimitiveType(),
2006b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom                             new_value, wide_value)) {
20133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return;
20233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
20333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
20433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  // Write the value.
20533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  SetFieldValue(o, f, wide_value, false);
20633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
20733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
208582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughesvoid Field_setBField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar src_descriptor, jbyte value) {
20933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue v = { 0 };
21033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  v.b = value;
211582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughes  SetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, src_descriptor, v);
21233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
21333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
214582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughesvoid Field_setCField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar src_descriptor, jchar value) {
21533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue v = { 0 };
21633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  v.c = value;
217582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughes  SetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, src_descriptor, v);
21833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
21933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
220582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughesvoid Field_setDField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar src_descriptor, jdouble value) {
22133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue v = { 0 };
22233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  v.d = value;
223582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughes  SetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, src_descriptor, v);
22433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
22533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
226582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughesvoid Field_setFField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar src_descriptor, jfloat value) {
22733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue v = { 0 };
22833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  v.f = value;
229582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughes  SetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, src_descriptor, v);
23033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
23133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
232582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughesvoid Field_setIField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar src_descriptor, jint value) {
23333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue v = { 0 };
23433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  v.i = value;
235582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughes  SetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, src_descriptor, v);
23633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
23733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
238582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughesvoid Field_setJField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar src_descriptor, jlong value) {
23933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue v = { 0 };
24033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  v.j = value;
241582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughes  SetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, src_descriptor, v);
24233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
24333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
244582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughesvoid Field_setSField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar src_descriptor, jshort value) {
24533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue v = { 0 };
24633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  v.s = value;
247582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughes  SetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, src_descriptor, v);
24833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
24933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
250582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughesvoid Field_setZField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jchar src_descriptor, jboolean value) {
25133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue v = { 0 };
25233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  v.z = value;
253582a7d16bb0db323d8bd730beb61578aa3765f43Elliott Hughes  SetPrimitiveField(env, javaField, javaObj, javaDeclaringClass, src_descriptor, v);
25433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
25533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
25633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughesvoid Field_setField(JNIEnv* env, jobject javaField, jobject javaObj, jclass javaDeclaringClass, jclass, jint, jboolean, jobject javaValue) {
257418d20fc407052d4152157f61e7453359f902383Elliott Hughes  Field* f = DecodeField(env->FromReflectedField(javaField));
25833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
25933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  // Unbox the value, if necessary.
26033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  Object* boxed_value = Decode<Object*>(env, javaValue);
26133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue unboxed_value;
26233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  if (!UnboxPrimitive(env, boxed_value, f->GetType(), unboxed_value)) {
26333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return;
26433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
26533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
26633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  // Check that the receiver is non-null and an instance of the field's declaring class.
267ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes  Object* o = NULL;
268ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes  if (!CheckReceiver(env, javaObj, javaDeclaringClass, f, o)) {
269ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes    return;
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));
277ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes  Object* o = NULL;
278ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes  if (!CheckReceiver(env, javaObj, javaDeclaringClass, f, o)) {
279ed1c1e335acc9f61c7e25a78204f159ee3d13350Elliott Hughes    return NULL;
28033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
28133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
28233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  // Get the field's value, boxing if necessary.
28333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  JValue value;
28433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  if (!GetFieldValue(o, f, value, true)) {
28533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes    return NULL;
28633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  }
2876b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  BoxPrimitive(env, f->GetPrimitiveType(), value);
28833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
28933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  return AddLocalReference<jobject>(env, value.l);
29033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes}
29133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
292f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstromstatic JNINativeMethod gMethods[] = {
29333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, getFieldModifiers, "(Ljava/lang/Class;I)I"),
29433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes
29533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, getBField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)B"),
29633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, getCField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)C"),
29733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, getDField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)D"),
29833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, getFField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)F"),
29933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, getField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZ)Ljava/lang/Object;"),
30033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, getIField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)I"),
30133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, getJField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)J"),
30233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, getSField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)S"),
30333203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, getZField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)Z"),
30433203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, setBField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCB)V"),
30533203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, setCField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCC)V"),
30633203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, setDField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCD)V"),
30733203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, setFField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCF)V"),
30833203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, setField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZLjava/lang/Object;)V"),
30933203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, setIField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCI)V"),
31033203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, setJField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCJ)V"),
31133203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, setSField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCS)V"),
31233203b59aa5f27bac0433bdb640f1f1e911186ebElliott Hughes  NATIVE_METHOD(Field, setZField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCZ)V"),
313f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom};
314f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom
315f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom}  // namespace
316f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom
317f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstromvoid register_java_lang_reflect_Field(JNIEnv* env) {
318418d20fc407052d4152157f61e7453359f902383Elliott Hughes  InitBoxingMethods(env); // TODO: move to Runtime?
319f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom  jniRegisterNativeMethods(env, "java/lang/reflect/Field", gMethods, NELEM(gMethods));
320f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom}
321f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom
322f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom}  // namespace art
323