entrypoint_utils.cc revision eac766769e3114a078c188ea26776a81f0edb3cf
12d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao/*
20f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * Copyright (C) 2012 The Android Open Source Project
32d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao *
42d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao * Licensed under the Apache License, Version 2.0 (the "License");
52d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao * you may not use this file except in compliance with the License.
62d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao * You may obtain a copy of the License at
72d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao *
82d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao *      http://www.apache.org/licenses/LICENSE-2.0
92d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao *
102d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao * Unless required by applicable law or agreed to in writing, software
112d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao * distributed under the License is distributed on an "AS IS" BASIS,
122d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao * See the License for the specific language governing permissions and
142d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao * limitations under the License.
152d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao */
162d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao
172d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao#include "runtime_support.h"
182d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao
195bb8601175bbb9cd761c715f4ba04f84d65e913bTDYa#include "ScopedLocalRef.h"
20eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes#include "well_known_classes.h"
215bb8601175bbb9cd761c715f4ba04f84d65e913bTDYa
2241005ddb5576b8630a1084fbb3979ffa602c0599jeffhaodouble art_l2d(int64_t l) {
2341005ddb5576b8630a1084fbb3979ffa602c0599jeffhao  return (double) l;
2441005ddb5576b8630a1084fbb3979ffa602c0599jeffhao}
2541005ddb5576b8630a1084fbb3979ffa602c0599jeffhao
2641005ddb5576b8630a1084fbb3979ffa602c0599jeffhaofloat art_l2f(int64_t l) {
2741005ddb5576b8630a1084fbb3979ffa602c0599jeffhao  return (float) l;
2841005ddb5576b8630a1084fbb3979ffa602c0599jeffhao}
292d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao
30776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers/*
31776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Float/double conversion requires clamping to min and max of integer form.  If
32776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * target doesn't support this normally, use these.
33776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */
3441005ddb5576b8630a1084fbb3979ffa602c0599jeffhaoint64_t art_d2l(double d) {
35776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  static const double kMaxLong = (double) (int64_t) 0x7fffffffffffffffULL;
36776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  static const double kMinLong = (double) (int64_t) 0x8000000000000000ULL;
37776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  if (d >= kMaxLong) {
38776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    return (int64_t) 0x7fffffffffffffffULL;
39776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else if (d <= kMinLong) {
40776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    return (int64_t) 0x8000000000000000ULL;
41776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else if (d != d)  { // NaN case
42776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    return 0;
43776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else {
44776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    return (int64_t) d;
45776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
46776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
47776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
4841005ddb5576b8630a1084fbb3979ffa602c0599jeffhaoint64_t art_f2l(float f) {
49776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  static const float kMaxLong = (float) (int64_t) 0x7fffffffffffffffULL;
50776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  static const float kMinLong = (float) (int64_t) 0x8000000000000000ULL;
51776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  if (f >= kMaxLong) {
52776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    return (int64_t) 0x7fffffffffffffffULL;
53776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else if (f <= kMinLong) {
54776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    return (int64_t) 0x8000000000000000ULL;
55776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else if (f != f) { // NaN case
56776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    return 0;
57776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else {
58776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    return (int64_t) f;
59776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
60776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
61776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
6241005ddb5576b8630a1084fbb3979ffa602c0599jeffhaoint32_t art_d2i(double d) {
63776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  static const double kMaxInt = (double) (int32_t) 0x7fffffffUL;
64776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  static const double kMinInt = (double) (int32_t) 0x80000000UL;
65776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  if (d >= kMaxInt) {
66776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    return (int32_t) 0x7fffffffUL;
67776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else if (d <= kMinInt) {
68776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    return (int32_t) 0x80000000UL;
69776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else if (d != d)  { // NaN case
70776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    return 0;
71776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else {
72776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    return (int32_t) d;
73776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
74776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
75776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
7641005ddb5576b8630a1084fbb3979ffa602c0599jeffhaoint32_t art_f2i(float f) {
77776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  static const float kMaxInt = (float) (int32_t) 0x7fffffffUL;
78776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  static const float kMinInt = (float) (int32_t) 0x80000000UL;
79776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  if (f >= kMaxInt) {
80776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    return (int32_t) 0x7fffffffUL;
81776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else if (f <= kMinInt) {
82776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    return (int32_t) 0x80000000UL;
83776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else if (f != f) { // NaN case
84776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    return 0;
85776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else {
86776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    return (int32_t) f;
87776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
88776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
89776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
9041005ddb5576b8630a1084fbb3979ffa602c0599jeffhaonamespace art {
9141005ddb5576b8630a1084fbb3979ffa602c0599jeffhao
9257b86d47b66322693a070185fadfb43cb9c12eabIan Rogersvoid ThrowNewIllegalAccessErrorClass(Thread* self,
9357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                     Class* referrer,
9457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                     Class* accessed) {
9557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  self->ThrowNewExceptionF("Ljava/lang/IllegalAccessError;",
9657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           "illegal class access: '%s' -> '%s'",
9757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           PrettyDescriptor(referrer).c_str(),
9857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           PrettyDescriptor(accessed).c_str());
9957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers}
10057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
10157b86d47b66322693a070185fadfb43cb9c12eabIan Rogersvoid ThrowNewIllegalAccessErrorClassForMethodDispatch(Thread* self,
10257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                                      Class* referrer,
10357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                                      Class* accessed,
10457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                                      const Method* caller,
10557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                                      const Method* called,
10657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                                      InvokeType type) {
10757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  std::ostringstream type_stream;
10857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  type_stream << type;
10957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  self->ThrowNewExceptionF("Ljava/lang/IllegalAccessError;",
11057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           "illegal class access ('%s' -> '%s')"
11157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           "in attempt to invoke %s method '%s' from '%s'",
11257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           PrettyDescriptor(referrer).c_str(),
11357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           PrettyDescriptor(accessed).c_str(),
11457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           type_stream.str().c_str(),
11557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           PrettyMethod(called).c_str(),
11657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           PrettyMethod(caller).c_str());
11757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers}
11857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
11957b86d47b66322693a070185fadfb43cb9c12eabIan Rogersvoid ThrowNewIncompatibleClassChangeErrorClassForInterfaceDispatch(Thread* self,
12057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                                                   const Method* referrer,
12157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                                                   const Method* interface_method,
12257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                                                   Object* this_object) {
12357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  self->ThrowNewExceptionF("Ljava/lang/IncompatibleClassChangeError;",
12457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           "class '%s' does not implement interface '%s' in call to '%s' from '%s'",
12557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           PrettyDescriptor(this_object->GetClass()).c_str(),
12657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           PrettyDescriptor(interface_method->GetDeclaringClass()).c_str(),
12757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           PrettyMethod(interface_method).c_str(), PrettyMethod(referrer).c_str());
12857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers}
12957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
13057b86d47b66322693a070185fadfb43cb9c12eabIan Rogersvoid ThrowNewIllegalAccessErrorField(Thread* self,
13157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                     Class* referrer,
13257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                     Field* accessed) {
13357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  self->ThrowNewExceptionF("Ljava/lang/IllegalAccessError;",
13457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           "Field '%s' is inaccessible to class '%s'",
13557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           PrettyField(accessed, false).c_str(),
13657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           PrettyDescriptor(referrer).c_str());
13757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers}
13857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
13957b86d47b66322693a070185fadfb43cb9c12eabIan Rogersvoid ThrowNewIllegalAccessErrorFinalField(Thread* self,
14057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                          const Method* referrer,
14157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                          Field* accessed) {
14257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  self->ThrowNewExceptionF("Ljava/lang/IllegalAccessError;",
14357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           "Final field '%s' cannot be written to by method '%s'",
14457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           PrettyField(accessed, false).c_str(),
14557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           PrettyMethod(referrer).c_str());
14657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers}
14757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
14857b86d47b66322693a070185fadfb43cb9c12eabIan Rogersvoid ThrowNewIllegalAccessErrorMethod(Thread* self,
14957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                      Class* referrer,
15057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                      Method* accessed) {
15157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  self->ThrowNewExceptionF("Ljava/lang/IllegalAccessError;",
15257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           "Method '%s' is inaccessible to class '%s'",
15357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           PrettyMethod(accessed).c_str(),
15457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           PrettyDescriptor(referrer).c_str());
15557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers}
15657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
15757b86d47b66322693a070185fadfb43cb9c12eabIan Rogersvoid ThrowNullPointerExceptionForFieldAccess(Thread* self,
15857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                                           Field* field,
15957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                                           bool is_read) {
16057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  self->ThrowNewExceptionF("Ljava/lang/NullPointerException;",
16157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           "Attempt to %s field '%s' on a null object reference",
16257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           is_read ? "read from" : "write to",
16357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           PrettyField(field, true).c_str());
16457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers}
16557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
16657b86d47b66322693a070185fadfb43cb9c12eabIan Rogersvoid ThrowNullPointerExceptionForMethodAccess(Thread* self,
16757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                              Method* caller,
16857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                              uint32_t method_idx,
16957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                              InvokeType type) {
17057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  const DexFile& dex_file =
17157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers      Runtime::Current()->GetClassLinker()->FindDexFile(caller->GetDeclaringClass()->GetDexCache());
17257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  std::ostringstream type_stream;
17357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  type_stream << type;
17457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  self->ThrowNewExceptionF("Ljava/lang/NullPointerException;",
17557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           "Attempt to invoke %s method '%s' on a null object reference",
17657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           type_stream.str().c_str(),
17757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           PrettyMethod(method_idx, dex_file, true).c_str());
17857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers}
17957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
1803f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYavoid ThrowNullPointerExceptionFromDexPC(Thread* self, Method* throw_method, uint32_t dex_pc) {
1813f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa  const DexFile::CodeItem* code = MethodHelper(throw_method).GetCodeItem();
1823f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa  CHECK_LT(dex_pc, code->insns_size_in_code_units_);
1833f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa  const Instruction* instr = Instruction::At(&code->insns_[dex_pc]);
1843f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa  DecodedInstruction dec_insn(instr);
1853f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa  switch (instr->Opcode()) {
1863f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::INVOKE_DIRECT:
1873f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::INVOKE_DIRECT_RANGE:
1883f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa      ThrowNullPointerExceptionForMethodAccess(self, throw_method, dec_insn.vB, kDirect);
1893f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa      break;
1903f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::INVOKE_VIRTUAL:
1913f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::INVOKE_VIRTUAL_RANGE:
1923f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa      ThrowNullPointerExceptionForMethodAccess(self, throw_method, dec_insn.vB, kVirtual);
1933f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa      break;
1943f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::IGET:
1953f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::IGET_WIDE:
1963f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::IGET_OBJECT:
1973f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::IGET_BOOLEAN:
1983f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::IGET_BYTE:
1993f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::IGET_CHAR:
2003f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::IGET_SHORT: {
2013f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa      Field* field =
2023f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa          Runtime::Current()->GetClassLinker()->ResolveField(dec_insn.vC, throw_method, false);
2033f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa      ThrowNullPointerExceptionForFieldAccess(self, field, true /* read */);
2043f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa      break;
2053f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    }
2063f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::IPUT:
2073f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::IPUT_WIDE:
2083f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::IPUT_OBJECT:
2093f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::IPUT_BOOLEAN:
2103f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::IPUT_BYTE:
2113f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::IPUT_CHAR:
2123f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::IPUT_SHORT: {
2133f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa      Field* field =
2143f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa          Runtime::Current()->GetClassLinker()->ResolveField(dec_insn.vC, throw_method, false);
2153f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa      ThrowNullPointerExceptionForFieldAccess(self, field, false /* write */);
2163f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa      break;
2173f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    }
2183f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::AGET:
2193f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::AGET_WIDE:
2203f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::AGET_OBJECT:
2213f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::AGET_BOOLEAN:
2223f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::AGET_BYTE:
2233f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::AGET_CHAR:
2243f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::AGET_SHORT:
2253f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa      self->ThrowNewException("Ljava/lang/NullPointerException;",
2263f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa                              "Attempt to read from null array");
2273f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa      break;
2283f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::APUT:
2293f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::APUT_WIDE:
2303f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::APUT_OBJECT:
2313f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::APUT_BOOLEAN:
2323f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::APUT_BYTE:
2333f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::APUT_CHAR:
2343f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    case Instruction::APUT_SHORT:
2353f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa      self->ThrowNewException("Ljava/lang/NullPointerException;",
2363f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa                              "Attempt to write to null array");
2373f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa      break;
2383f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    default: {
2393f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa      const DexFile& dex_file = Runtime::Current()->GetClassLinker()
2403f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa          ->FindDexFile(throw_method->GetDeclaringClass()->GetDexCache());
2413f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa      std::string message("Null pointer exception during instruction '");
2423f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa      message += instr->DumpString(&dex_file);
2433f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa      message += "'";
2443f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa      self->ThrowNewException("Ljava/lang/NullPointerException;", message.c_str());
2453f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa      break;
2463f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa    }
2473f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa  }
2483f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa}
2493f9137d85b3c2c0800fb26e3415ace1a6b7cc4deTDYa
25057b86d47b66322693a070185fadfb43cb9c12eabIan Rogersstd::string FieldNameFromIndex(const Method* method, uint32_t ref,
25157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                               verifier::VerifyErrorRefType ref_type, bool access) {
252d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  CHECK_EQ(static_cast<int>(ref_type), static_cast<int>(verifier::VERIFY_ERROR_REF_FIELD));
2536c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes
2546c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
2556c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes  const DexFile& dex_file = class_linker->FindDexFile(method->GetDeclaringClass()->GetDexCache());
2566c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes
2576c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes  const DexFile::FieldId& id = dex_file.GetFieldId(ref);
2586b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  std::string class_name(PrettyDescriptor(dex_file.GetFieldDeclaringClassDescriptor(id)));
2590571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  const char* field_name = dex_file.StringDataByIdx(id.name_idx_);
2606c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes  if (!access) {
2616c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes    return class_name + "." + field_name;
2626c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes  }
2636c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes
2646c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes  std::string result;
2656c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes  result += "tried to access field ";
2666c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes  result += class_name + "." + field_name;
2676c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes  result += " from class ";
2686d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  result += PrettyDescriptor(method->GetDeclaringClass());
2696c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes  return result;
2706c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes}
2716c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes
27257b86d47b66322693a070185fadfb43cb9c12eabIan Rogersstd::string MethodNameFromIndex(const Method* method, uint32_t ref,
27357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                verifier::VerifyErrorRefType ref_type, bool access) {
274d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  CHECK_EQ(static_cast<int>(ref_type), static_cast<int>(verifier::VERIFY_ERROR_REF_METHOD));
2756c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes
2766c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
2776c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes  const DexFile& dex_file = class_linker->FindDexFile(method->GetDeclaringClass()->GetDexCache());
2786c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes
2796c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes  const DexFile::MethodId& id = dex_file.GetMethodId(ref);
2806b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  std::string class_name(PrettyDescriptor(dex_file.GetMethodDeclaringClassDescriptor(id)));
2810571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  const char* method_name = dex_file.StringDataByIdx(id.name_idx_);
2826c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes  if (!access) {
2836c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes    return class_name + "." + method_name;
2846c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes  }
2856c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes
2866c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes  std::string result;
2876c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes  result += "tried to access method ";
2884f0d07c783afef89703dce32c94440fc8621a29bIan Rogers  result += class_name + "." + method_name + ":" +
2890571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers      dex_file.CreateMethodSignature(id.proto_idx_, NULL);
2906c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes  result += " from class ";
2916d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  result += PrettyDescriptor(method->GetDeclaringClass());
2926c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes  return result;
2936c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes}
2946c8867daab4af4667e0e816f6beafa7c5d13e043Elliott Hughes
295b92bcabcbb28f69fe99e1c2f2e5559ab2c47aa60TDYastatic std::string ClassNameFromIndex(const Method* method, uint32_t ref,
296b92bcabcbb28f69fe99e1c2f2e5559ab2c47aa60TDYa                                      verifier::VerifyErrorRefType ref_type, bool access) {
2979e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
2989e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  const DexFile& dex_file = class_linker->FindDexFile(method->GetDeclaringClass()->GetDexCache());
2999e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien
3009e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  uint16_t type_idx = 0;
3019e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  if (ref_type == verifier::VERIFY_ERROR_REF_FIELD) {
3029e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    const DexFile::FieldId& id = dex_file.GetFieldId(ref);
3039e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    type_idx = id.class_idx_;
3049e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  } else if (ref_type == verifier::VERIFY_ERROR_REF_METHOD) {
3059e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    const DexFile::MethodId& id = dex_file.GetMethodId(ref);
3069e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    type_idx = id.class_idx_;
3079e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  } else if (ref_type == verifier::VERIFY_ERROR_REF_CLASS) {
3089e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    type_idx = ref;
3099e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  } else {
3109e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    CHECK(false) << static_cast<int>(ref_type);
3119e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  }
3129e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien
3139e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  std::string class_name(PrettyDescriptor(dex_file.StringByTypeIdx(type_idx)));
3149e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  if (!access) {
3159e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    return class_name;
3169e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  }
3179e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien
3189e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  std::string result;
3199e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  result += "tried to access class ";
3209e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  result += class_name;
3219e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  result += " from class ";
3229e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  result += PrettyDescriptor(method->GetDeclaringClass());
3239e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  return result;
3249e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien}
3259e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien
3269e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chienvoid ThrowVerificationError(Thread* self, const Method* method,
3279e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien                            int32_t kind, int32_t ref) {
3289e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  verifier::VerifyErrorRefType ref_type =
3299e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien      static_cast<verifier::VerifyErrorRefType>(kind >> verifier::kVerifyErrorRefTypeShift);
3309e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien
3319e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  const char* exception_class = "Ljava/lang/VerifyError;";
3329e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  std::string msg;
3339e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien
3349e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  switch (static_cast<verifier::VerifyError>(kind & ~(0xff << verifier::kVerifyErrorRefTypeShift))) {
3359e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  case verifier::VERIFY_ERROR_NO_CLASS:
3369e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    exception_class = "Ljava/lang/NoClassDefFoundError;";
3379e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    msg = ClassNameFromIndex(method, ref, ref_type, false);
3389e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    break;
3399e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  case verifier::VERIFY_ERROR_NO_FIELD:
3409e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    exception_class = "Ljava/lang/NoSuchFieldError;";
3419e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    msg = FieldNameFromIndex(method, ref, ref_type, false);
3429e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    break;
3439e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  case verifier::VERIFY_ERROR_NO_METHOD:
3449e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    exception_class = "Ljava/lang/NoSuchMethodError;";
3459e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    msg = MethodNameFromIndex(method, ref, ref_type, false);
3469e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    break;
3479e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  case verifier::VERIFY_ERROR_ACCESS_CLASS:
3489e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    exception_class = "Ljava/lang/IllegalAccessError;";
3499e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    msg = ClassNameFromIndex(method, ref, ref_type, true);
3509e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    break;
3519e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  case verifier::VERIFY_ERROR_ACCESS_FIELD:
3529e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    exception_class = "Ljava/lang/IllegalAccessError;";
3539e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    msg = FieldNameFromIndex(method, ref, ref_type, true);
3549e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    break;
3559e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  case verifier::VERIFY_ERROR_ACCESS_METHOD:
3569e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    exception_class = "Ljava/lang/IllegalAccessError;";
3579e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    msg = MethodNameFromIndex(method, ref, ref_type, true);
3589e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    break;
3599e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  case verifier::VERIFY_ERROR_CLASS_CHANGE:
3609e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    exception_class = "Ljava/lang/IncompatibleClassChangeError;";
3619e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    msg = ClassNameFromIndex(method, ref, ref_type, false);
3629e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    break;
3639e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  case verifier::VERIFY_ERROR_INSTANTIATION:
3649e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    exception_class = "Ljava/lang/InstantiationError;";
3659e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    msg = ClassNameFromIndex(method, ref, ref_type, false);
3669e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    break;
3679e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  case verifier::VERIFY_ERROR_BAD_CLASS_SOFT:
3689e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  case verifier::VERIFY_ERROR_BAD_CLASS_HARD:
3699e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    // Generic VerifyError; use default exception, no message.
3709e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien    break;
3719e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  }
3729e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien
3739e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien  self->ThrowNewException(exception_class, msg.c_str());
3749e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien}
3759e5f5c1dc6cc6551db082fdcf484a145bfb684fdLogan Chien
37657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers// Helper function to allocate array for FILLED_NEW_ARRAY.
37757b86d47b66322693a070185fadfb43cb9c12eabIan RogersArray* CheckAndAllocArrayFromCode(uint32_t type_idx, Method* method, int32_t component_count,
37857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                  Thread* self, bool access_check) {
37957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  if (UNLIKELY(component_count < 0)) {
38057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    self->ThrowNewExceptionF("Ljava/lang/NegativeArraySizeException;", "%d", component_count);
38157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    return NULL;  // Failure
382ea2a11d5f20814f17985ae3d4defc8dd843f19b9Ian Rogers  }
38357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  Class* klass = method->GetDexCacheResolvedTypes()->Get(type_idx);
38457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  if (UNLIKELY(klass == NULL)) {  // Not in dex cache so try to resolve
38557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    klass = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, method);
38657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    if (klass == NULL) {  // Error
38757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers      DCHECK(Thread::Current()->IsExceptionPending());
38857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers      return NULL;  // Failure
389ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers    }
390ea2a11d5f20814f17985ae3d4defc8dd843f19b9Ian Rogers  }
39157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  if (UNLIKELY(klass->IsPrimitive() && !klass->IsPrimitiveInt())) {
39257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    if (klass->IsPrimitiveLong() || klass->IsPrimitiveDouble()) {
39357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers      Thread::Current()->ThrowNewExceptionF("Ljava/lang/RuntimeException;",
39457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                            "Bad filled array request for type %s",
39557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                            PrettyDescriptor(klass).c_str());
396573db4a2077380d81fa74ee2309162530db87a98Ian Rogers    } else {
39757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers      Thread::Current()->ThrowNewExceptionF("Ljava/lang/InternalError;",
39857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                            "Found type %s; filled-new-array not implemented for anything but \'int\'",
39957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                            PrettyDescriptor(klass).c_str());
400573db4a2077380d81fa74ee2309162530db87a98Ian Rogers    }
40157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    return NULL;  // Failure
402ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers  } else {
40357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    if (access_check) {
40457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers      Class* referrer = method->GetDeclaringClass();
40557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers      if (UNLIKELY(!referrer->CanAccess(klass))) {
40657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        ThrowNewIllegalAccessErrorClass(self, referrer, klass);
40757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        return NULL;  // Failure
40857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers      }
40957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    }
41057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    DCHECK(klass->IsArrayClass()) << PrettyClass(klass);
41157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    return Array::Alloc(klass, component_count);
412ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers  }
413ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers}
414ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers
41557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers// Slow path field resolution and declaring class initialization
41657b86d47b66322693a070185fadfb43cb9c12eabIan RogersField* FindFieldFromCode(uint32_t field_idx, const Method* referrer, Thread* self,
41757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                         bool is_static, bool is_primitive, bool is_set, size_t expected_size) {
41857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
41957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  Field* resolved_field = class_linker->ResolveField(field_idx, referrer, is_static);
42057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  if (UNLIKELY(resolved_field == NULL)) {
42157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    DCHECK(self->IsExceptionPending());  // Throw exception and unwind
42257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    return NULL;  // failure
42357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  } else {
42457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    Class* fields_class = resolved_field->GetDeclaringClass();
42557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    Class* referring_class = referrer->GetDeclaringClass();
426e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers    if (UNLIKELY(!referring_class->CanAccess(fields_class) ||
427e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                 !referring_class->CanAccessMember(fields_class,
428e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                                                   resolved_field->GetAccessFlags()))) {
429e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      // The referring class can't access the resolved field, this may occur as a result of a
430e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      // protected field being made public by a sub-class. Resort to the dex file to determine
431e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      // the correct class for the access check.
432e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      const DexFile& dex_file = class_linker->FindDexFile(referring_class->GetDexCache());
433e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      fields_class = class_linker->ResolveType(dex_file,
434e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                                               dex_file.GetFieldId(field_idx).class_idx_,
435e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                                               referring_class);
436e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      if (UNLIKELY(!referring_class->CanAccess(fields_class))) {
437e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        ThrowNewIllegalAccessErrorClass(self, referring_class, fields_class);
438e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        return NULL;  // failure
439e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      } else if (UNLIKELY(!referring_class->CanAccessMember(fields_class,
440e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                                                            resolved_field->GetAccessFlags()))) {
441e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        ThrowNewIllegalAccessErrorField(self, referring_class, resolved_field);
442e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        return NULL;  // failure
443e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      }
444e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers    }
445e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers    if (UNLIKELY(is_set && resolved_field->IsFinal() && (fields_class != referring_class))) {
44657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers      ThrowNewIllegalAccessErrorFinalField(self, referrer, resolved_field);
44757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers      return NULL;  // failure
44857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    } else {
44957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers      FieldHelper fh(resolved_field);
45057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers      if (UNLIKELY(fh.IsPrimitiveType() != is_primitive ||
45157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                   fh.FieldSize() != expected_size)) {
45257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        self->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
45357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                 "Attempted read of %zd-bit %s on field '%s'",
45457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                 expected_size * (32 / sizeof(int32_t)),
45557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                 is_primitive ? "primitive" : "non-primitive",
45657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                 PrettyField(resolved_field, true).c_str());
45757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        return NULL;  // failure
45857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers      } else if (!is_static) {
45957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        // instance fields must be being accessed on an initialized class
46057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        return resolved_field;
46160db5ab3a2e480db9236325a14cb5a867881d8bbIan Rogers      } else {
46257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        // If the class is already initializing, we must be inside <clinit>, or
46357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        // we'd still be waiting for the lock.
46457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        if (fields_class->IsInitializing()) {
46557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers          return resolved_field;
4660045a290e6b79a274250e3112880c04bde437d4aIan Rogers        } else if (Runtime::Current()->GetClassLinker()->EnsureInitialized(fields_class, true, true)) {
46757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers          return resolved_field;
46860db5ab3a2e480db9236325a14cb5a867881d8bbIan Rogers        } else {
46957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers          DCHECK(self->IsExceptionPending());  // Throw exception and unwind
47057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers          return NULL;  // failure
47160db5ab3a2e480db9236325a14cb5a867881d8bbIan Rogers        }
47260db5ab3a2e480db9236325a14cb5a867881d8bbIan Rogers      }
47360db5ab3a2e480db9236325a14cb5a867881d8bbIan Rogers    }
47460db5ab3a2e480db9236325a14cb5a867881d8bbIan Rogers  }
475ddbd01ac1660d57416879d5a576482f1048dde64Shih-wei Liao}
476ddbd01ac1660d57416879d5a576482f1048dde64Shih-wei Liao
47757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers// Slow path method resolution
47857b86d47b66322693a070185fadfb43cb9c12eabIan RogersMethod* FindMethodFromCode(uint32_t method_idx, Object* this_object, const Method* referrer,
47957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                           Thread* self, bool access_check, InvokeType type) {
48057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
48157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  bool is_direct = type == kStatic || type == kDirect;
48257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  Method* resolved_method = class_linker->ResolveMethod(method_idx, referrer, is_direct);
48357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  if (UNLIKELY(resolved_method == NULL)) {
48457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    DCHECK(self->IsExceptionPending());  // Throw exception and unwind
48557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    return NULL;  // failure
486466bb25416b88fabd5d4387b7c7e5cc1ece78b8cIan Rogers  } else {
48757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    if (!access_check) {
48857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers      if (is_direct) {
48957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        return resolved_method;
49057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers      } else if (type == kInterface) {
49157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        Method* interface_method =
49257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers            this_object->GetClass()->FindVirtualMethodForInterface(resolved_method);
49357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        if (UNLIKELY(interface_method == NULL)) {
49457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers          ThrowNewIncompatibleClassChangeErrorClassForInterfaceDispatch(self, referrer,
49557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                                                        resolved_method,
49657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                                                        this_object);
49757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers          return NULL;  // failure
49857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        } else {
49957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers          return interface_method;
50057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        }
50157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers      } else {
50257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        ObjectArray<Method>* vtable;
50357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        uint16_t vtable_index = resolved_method->GetMethodIndex();
50457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        if (type == kSuper) {
50557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers          vtable = referrer->GetDeclaringClass()->GetSuperClass()->GetVTable();
50657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        } else {
50757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers          vtable = this_object->GetClass()->GetVTable();
50857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        }
50957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        // TODO: eliminate bounds check?
51057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        return vtable->Get(vtable_index);
511051c9fc1de07bbc265af38cf60f061394163c68fElliott Hughes      }
512466bb25416b88fabd5d4387b7c7e5cc1ece78b8cIan Rogers    } else {
51357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers      Class* methods_class = resolved_method->GetDeclaringClass();
51457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers      Class* referring_class = referrer->GetDeclaringClass();
51557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers      if (UNLIKELY(!referring_class->CanAccess(methods_class) ||
51657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                   !referring_class->CanAccessMember(methods_class,
51757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                                     resolved_method->GetAccessFlags()))) {
51857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        // The referring class can't access the resolved method, this may occur as a result of a
51957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        // protected method being made public by implementing an interface that re-declares the
52057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        // method public. Resort to the dex file to determine the correct class for the access check
52157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        const DexFile& dex_file = class_linker->FindDexFile(referring_class->GetDexCache());
52257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        methods_class = class_linker->ResolveType(dex_file,
52357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                                  dex_file.GetMethodId(method_idx).class_idx_,
52457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                                  referring_class);
52557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        if (UNLIKELY(!referring_class->CanAccess(methods_class))) {
52657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers          ThrowNewIllegalAccessErrorClassForMethodDispatch(self, referring_class, methods_class,
52757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                                           referrer, resolved_method, type);
52857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers          return NULL;  // failure
52957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        } else if (UNLIKELY(!referring_class->CanAccessMember(methods_class,
53057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                                              resolved_method->GetAccessFlags()))) {
53157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers          ThrowNewIllegalAccessErrorMethod(self, referring_class, resolved_method);
53257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers          return NULL;  // failure
533c2b4447ae9c0c1e77595620acac6508999df6698Ian Rogers        }
534c2b4447ae9c0c1e77595620acac6508999df6698Ian Rogers      }
53557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers      if (is_direct) {
53657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        return resolved_method;
53757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers      } else if (type == kInterface) {
53857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        Method* interface_method =
53957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers            this_object->GetClass()->FindVirtualMethodForInterface(resolved_method);
54057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        if (UNLIKELY(interface_method == NULL)) {
54157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers          ThrowNewIncompatibleClassChangeErrorClassForInterfaceDispatch(self, referrer,
54257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                                                        resolved_method,
54357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                                                        this_object);
54457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers          return NULL;  // failure
54557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        } else {
54657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers          return interface_method;
54757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        }
548466bb25416b88fabd5d4387b7c7e5cc1ece78b8cIan Rogers      } else {
54957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        ObjectArray<Method>* vtable;
55057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        uint16_t vtable_index = resolved_method->GetMethodIndex();
55157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        if (type == kSuper) {
55257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers          Class* super_class = referring_class->GetSuperClass();
55357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers          if (LIKELY(super_class != NULL)) {
55457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers            vtable = referring_class->GetSuperClass()->GetVTable();
55557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers          } else {
55657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers            vtable = NULL;
55757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers          }
55857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        } else {
55957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers          vtable = this_object->GetClass()->GetVTable();
56057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        }
56157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        if (LIKELY(vtable != NULL &&
56257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                   vtable_index < static_cast<uint32_t>(vtable->GetLength()))) {
56357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers          return vtable->GetWithoutChecks(vtable_index);
56457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        } else {
56557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers          // Behavior to agree with that of the verifier
56657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers          self->ThrowNewExceptionF("Ljava/lang/NoSuchMethodError;",
56757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                   "attempt to invoke %s method '%s' from '%s'"
56857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                   " using incorrect form of method dispatch",
56957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                   (type == kSuper ? "super class" : "virtual"),
57057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                   PrettyMethod(resolved_method).c_str(),
57157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                                   PrettyMethod(referrer).c_str());
57257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers          return NULL;  // failure
57357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        }
574466bb25416b88fabd5d4387b7c7e5cc1ece78b8cIan Rogers      }
575466bb25416b88fabd5d4387b7c7e5cc1ece78b8cIan Rogers    }
576dfcdf1a0d2d8d75b4c701317e4a092498a8d1e9eIan Rogers  }
577dfcdf1a0d2d8d75b4c701317e4a092498a8d1e9eIan Rogers}
578dfcdf1a0d2d8d75b4c701317e4a092498a8d1e9eIan Rogers
57957b86d47b66322693a070185fadfb43cb9c12eabIan RogersClass* ResolveVerifyAndClinit(uint32_t type_idx, const Method* referrer, Thread* self,
58057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                               bool can_run_clinit, bool verify_access) {
58157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
58257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  Class* klass = class_linker->ResolveType(type_idx, referrer);
58357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  if (UNLIKELY(klass == NULL)) {
58457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    CHECK(self->IsExceptionPending());
58557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    return NULL;  // Failure - Indicate to caller to deliver exception
58657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  }
58757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  // Perform access check if necessary.
58857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  Class* referring_class = referrer->GetDeclaringClass();
58957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  if (verify_access && UNLIKELY(!referring_class->CanAccess(klass))) {
59057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    ThrowNewIllegalAccessErrorClass(self, referring_class, klass);
59157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    return NULL;  // Failure - Indicate to caller to deliver exception
59257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  }
59357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  // If we're just implementing const-class, we shouldn't call <clinit>.
59457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  if (!can_run_clinit) {
59557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    return klass;
59657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  }
59757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  // If we are the <clinit> of this class, just return our storage.
59857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  //
59957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  // Do not set the DexCache InitializedStaticStorage, since that implies <clinit> has finished
60057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  // running.
60157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  if (klass == referring_class && MethodHelper(referrer).IsClassInitializer()) {
60257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    return klass;
60357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  }
6040045a290e6b79a274250e3112880c04bde437d4aIan Rogers  if (!class_linker->EnsureInitialized(klass, true, true)) {
60557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    CHECK(self->IsExceptionPending());
60657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    return NULL;  // Failure - Indicate to caller to deliver exception
607a433b2e8edf91c8124abd8eb5b3bd558a40fc987Ian Rogers  }
60857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  referrer->GetDexCacheInitializedStaticStorage()->Set(type_idx, klass);
60957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  return klass;
6102d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao}
6112d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao
6125bb8601175bbb9cd761c715f4ba04f84d65e913bTDYavoid ThrowNewUndeclaredThrowableException(Thread* self, JNIEnv* env, Throwable* exception) {
613eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes  jmethodID jlre_UTE_constructor = env->GetMethodID(WellKnownClasses::java_lang_reflect_UndeclaredThrowableException, "<init>",
614eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes                                                    "(Ljava/lang/Throwable;)V");
615eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes  jthrowable jexception = AddLocalReference<jthrowable>(env, exception);
616eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes  ScopedLocalRef<jthrowable> jlr_UTE(env,
617eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes      reinterpret_cast<jthrowable>(env->NewObject(WellKnownClasses::java_lang_reflect_UndeclaredThrowableException,
618eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes      jlre_UTE_constructor, jexception)));
619eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes  int rc = env->Throw(jlr_UTE.get());
620eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes  if (rc != JNI_OK) {
6215bb8601175bbb9cd761c715f4ba04f84d65e913bTDYa    LOG(ERROR) << "Couldn't throw new \"java/lang/reflect/UndeclaredThrowableException\"";
6225bb8601175bbb9cd761c715f4ba04f84d65e913bTDYa  }
6235bb8601175bbb9cd761c715f4ba04f84d65e913bTDYa  CHECK(self->IsExceptionPending());
6245bb8601175bbb9cd761c715f4ba04f84d65e913bTDYa}
6255bb8601175bbb9cd761c715f4ba04f84d65e913bTDYa
6262d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao}  // namespace art
627