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