187e552db94588455c081efd87dbde0cd96d02942Ian Rogers/* 287e552db94588455c081efd87dbde0cd96d02942Ian Rogers * Copyright (C) 2012 The Android Open Source Project 387e552db94588455c081efd87dbde0cd96d02942Ian Rogers * 487e552db94588455c081efd87dbde0cd96d02942Ian Rogers * Licensed under the Apache License, Version 2.0 (the "License"); 587e552db94588455c081efd87dbde0cd96d02942Ian Rogers * you may not use this file except in compliance with the License. 687e552db94588455c081efd87dbde0cd96d02942Ian Rogers * You may obtain a copy of the License at 787e552db94588455c081efd87dbde0cd96d02942Ian Rogers * 887e552db94588455c081efd87dbde0cd96d02942Ian Rogers * http://www.apache.org/licenses/LICENSE-2.0 987e552db94588455c081efd87dbde0cd96d02942Ian Rogers * 1087e552db94588455c081efd87dbde0cd96d02942Ian Rogers * Unless required by applicable law or agreed to in writing, software 1187e552db94588455c081efd87dbde0cd96d02942Ian Rogers * distributed under the License is distributed on an "AS IS" BASIS, 1287e552db94588455c081efd87dbde0cd96d02942Ian Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1387e552db94588455c081efd87dbde0cd96d02942Ian Rogers * See the License for the specific language governing permissions and 1487e552db94588455c081efd87dbde0cd96d02942Ian Rogers * limitations under the License. 1587e552db94588455c081efd87dbde0cd96d02942Ian Rogers */ 1687e552db94588455c081efd87dbde0cd96d02942Ian Rogers 1787e552db94588455c081efd87dbde0cd96d02942Ian Rogers#include "common_throws.h" 1887e552db94588455c081efd87dbde0cd96d02942Ian Rogers 1922d5e735f403c57525fe868304c7123f0ce66399Ian Rogers#include <sstream> 2022d5e735f403c57525fe868304c7123f0ce66399Ian Rogers 2107ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "base/logging.h" 222dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "class_linker-inl.h" 234f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h" 2475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz#include "dex_instruction-inl.h" 2587e552db94588455c081efd87dbde0cd96d02942Ian Rogers#include "invoke_type.h" 26ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include "mirror/art_method-inl.h" 274f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "mirror/class-inl.h" 282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object-inl.h" 292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object_array-inl.h" 3087e552db94588455c081efd87dbde0cd96d02942Ian Rogers#include "thread.h" 312d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz#include "verifier/method_verifier.h" 3287e552db94588455c081efd87dbde0cd96d02942Ian Rogers 3387e552db94588455c081efd87dbde0cd96d02942Ian Rogersnamespace art { 3487e552db94588455c081efd87dbde0cd96d02942Ian Rogers 35ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersstatic void AddReferrerLocation(std::ostream& os, mirror::Class* referrer) 36b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 3787e552db94588455c081efd87dbde0cd96d02942Ian Rogers if (referrer != NULL) { 38f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier std::string location(referrer->GetLocation()); 3987e552db94588455c081efd87dbde0cd96d02942Ian Rogers if (!location.empty()) { 4062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers os << " (declaration of '" << PrettyDescriptor(referrer) 4162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers << "' appears in " << location << ")"; 4287e552db94588455c081efd87dbde0cd96d02942Ian Rogers } 4387e552db94588455c081efd87dbde0cd96d02942Ian Rogers } 4487e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 4587e552db94588455c081efd87dbde0cd96d02942Ian Rogers 4662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersstatic void ThrowException(const ThrowLocation* throw_location, const char* exception_descriptor, 47ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers mirror::Class* referrer, const char* fmt, va_list* args = NULL) 48b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 4962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers std::ostringstream msg; 5062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (args != NULL) { 5162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers std::string vmsg; 5262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers StringAppendV(&vmsg, fmt, *args); 5362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers msg << vmsg; 5462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } else { 5562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers msg << fmt; 5662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 5762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers AddReferrerLocation(msg, referrer); 5862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers Thread* self = Thread::Current(); 5962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (throw_location == NULL) { 6062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation computed_throw_location = self->GetCurrentLocationForThrow(); 6162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers self->ThrowNewException(computed_throw_location, exception_descriptor, msg.str().c_str()); 6262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } else { 6362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers self->ThrowNewException(*throw_location, exception_descriptor, msg.str().c_str()); 6487e552db94588455c081efd87dbde0cd96d02942Ian Rogers } 6587e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 6687e552db94588455c081efd87dbde0cd96d02942Ian Rogers 67329d18806792771dfee064203fe27875d79cd53aAndreas Gampestatic void ThrowWrappedException(const ThrowLocation* throw_location, 68329d18806792771dfee064203fe27875d79cd53aAndreas Gampe const char* exception_descriptor, 69329d18806792771dfee064203fe27875d79cd53aAndreas Gampe mirror::Class* referrer, const char* fmt, va_list* args = NULL) 70329d18806792771dfee064203fe27875d79cd53aAndreas Gampe SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 71329d18806792771dfee064203fe27875d79cd53aAndreas Gampe std::ostringstream msg; 72329d18806792771dfee064203fe27875d79cd53aAndreas Gampe if (args != NULL) { 73329d18806792771dfee064203fe27875d79cd53aAndreas Gampe std::string vmsg; 74329d18806792771dfee064203fe27875d79cd53aAndreas Gampe StringAppendV(&vmsg, fmt, *args); 75329d18806792771dfee064203fe27875d79cd53aAndreas Gampe msg << vmsg; 76329d18806792771dfee064203fe27875d79cd53aAndreas Gampe } else { 77329d18806792771dfee064203fe27875d79cd53aAndreas Gampe msg << fmt; 78329d18806792771dfee064203fe27875d79cd53aAndreas Gampe } 79329d18806792771dfee064203fe27875d79cd53aAndreas Gampe AddReferrerLocation(msg, referrer); 80329d18806792771dfee064203fe27875d79cd53aAndreas Gampe Thread* self = Thread::Current(); 81329d18806792771dfee064203fe27875d79cd53aAndreas Gampe if (throw_location == NULL) { 82329d18806792771dfee064203fe27875d79cd53aAndreas Gampe ThrowLocation computed_throw_location = self->GetCurrentLocationForThrow(); 83329d18806792771dfee064203fe27875d79cd53aAndreas Gampe self->ThrowNewWrappedException(computed_throw_location, exception_descriptor, msg.str().c_str()); 84329d18806792771dfee064203fe27875d79cd53aAndreas Gampe } else { 85329d18806792771dfee064203fe27875d79cd53aAndreas Gampe self->ThrowNewWrappedException(*throw_location, exception_descriptor, msg.str().c_str()); 86329d18806792771dfee064203fe27875d79cd53aAndreas Gampe } 87329d18806792771dfee064203fe27875d79cd53aAndreas Gampe} 88329d18806792771dfee064203fe27875d79cd53aAndreas Gampe 8956adf601ed9d1d11a2c462caa262e7de66a9e172Sebastien Hertz// AbstractMethodError 9056adf601ed9d1d11a2c462caa262e7de66a9e172Sebastien Hertz 91ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersvoid ThrowAbstractMethodError(mirror::ArtMethod* method) { 9256adf601ed9d1d11a2c462caa262e7de66a9e172Sebastien Hertz ThrowException(NULL, "Ljava/lang/AbstractMethodError;", NULL, 9356adf601ed9d1d11a2c462caa262e7de66a9e172Sebastien Hertz StringPrintf("abstract method \"%s\"", 9456adf601ed9d1d11a2c462caa262e7de66a9e172Sebastien Hertz PrettyMethod(method).c_str()).c_str()); 9556adf601ed9d1d11a2c462caa262e7de66a9e172Sebastien Hertz} 9656adf601ed9d1d11a2c462caa262e7de66a9e172Sebastien Hertz 9762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// ArithmeticException 9887e552db94588455c081efd87dbde0cd96d02942Ian Rogers 990a3b863fb1acae912b54f4be2c1928d3afa5e936Sebastien Hertzvoid ThrowArithmeticExceptionDivideByZero() { 10062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/ArithmeticException;", NULL, "divide by zero"); 10187e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 10287e552db94588455c081efd87dbde0cd96d02942Ian Rogers 10362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// ArrayIndexOutOfBoundsException 10462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 10562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowArrayIndexOutOfBoundsException(int index, int length) { 10662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/ArrayIndexOutOfBoundsException;", NULL, 10762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers StringPrintf("length=%d; index=%d", length, index).c_str()); 10887e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 10987e552db94588455c081efd87dbde0cd96d02942Ian Rogers 11062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// ArrayStoreException 11162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 112ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersvoid ThrowArrayStoreException(mirror::Class* element_class, mirror::Class* array_class) { 11362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/ArrayStoreException;", NULL, 11462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers StringPrintf("%s cannot be stored in an array of type %s", 11562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PrettyDescriptor(element_class).c_str(), 11662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PrettyDescriptor(array_class).c_str()).c_str()); 11762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 11862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 11962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// ClassCastException 12062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 121ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersvoid ThrowClassCastException(mirror::Class* dest_type, mirror::Class* src_type) { 12262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/ClassCastException;", NULL, 12362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers StringPrintf("%s cannot be cast to %s", 12462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PrettyDescriptor(src_type).c_str(), 12562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PrettyDescriptor(dest_type).c_str()).c_str()); 12662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 12762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 12862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowClassCastException(const ThrowLocation* throw_location, const char* msg) { 12962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(throw_location, "Ljava/lang/ClassCastException;", NULL, msg); 13062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 13162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 13262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// ClassCircularityError 13362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 13462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowClassCircularityError(mirror::Class* c) { 13562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers std::ostringstream msg; 13662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers msg << PrettyDescriptor(c); 13762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/ClassCircularityError;", c, msg.str().c_str()); 13887e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 13987e552db94588455c081efd87dbde0cd96d02942Ian Rogers 14062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// ClassFormatError 14162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 142ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersvoid ThrowClassFormatError(mirror::Class* referrer, const char* fmt, ...) { 14362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_list args; 14462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_start(args, fmt); 14562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/ClassFormatError;", referrer, fmt, &args); 14662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_end(args);} 14762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 14887e552db94588455c081efd87dbde0cd96d02942Ian Rogers// IllegalAccessError 14987e552db94588455c081efd87dbde0cd96d02942Ian Rogers 1502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid ThrowIllegalAccessErrorClass(mirror::Class* referrer, mirror::Class* accessed) { 15187e552db94588455c081efd87dbde0cd96d02942Ian Rogers std::ostringstream msg; 152b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers msg << "Illegal class access: '" << PrettyDescriptor(referrer) << "' attempting to access '" 15387e552db94588455c081efd87dbde0cd96d02942Ian Rogers << PrettyDescriptor(accessed) << "'"; 15462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str()); 15587e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 15687e552db94588455c081efd87dbde0cd96d02942Ian Rogers 1572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid ThrowIllegalAccessErrorClassForMethodDispatch(mirror::Class* referrer, mirror::Class* accessed, 158ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers mirror::ArtMethod* called, 15987e552db94588455c081efd87dbde0cd96d02942Ian Rogers InvokeType type) { 16087e552db94588455c081efd87dbde0cd96d02942Ian Rogers std::ostringstream msg; 161b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers msg << "Illegal class access ('" << PrettyDescriptor(referrer) << "' attempting to access '" 162b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers << PrettyDescriptor(accessed) << "') in attempt to invoke " << type 16387e552db94588455c081efd87dbde0cd96d02942Ian Rogers << " method " << PrettyMethod(called).c_str(); 16462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str()); 16587e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 16687e552db94588455c081efd87dbde0cd96d02942Ian Rogers 167ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromvoid ThrowIllegalAccessErrorMethod(mirror::Class* referrer, mirror::ArtMethod* accessed) { 16887e552db94588455c081efd87dbde0cd96d02942Ian Rogers std::ostringstream msg; 16987e552db94588455c081efd87dbde0cd96d02942Ian Rogers msg << "Method '" << PrettyMethod(accessed) << "' is inaccessible to class '" 17087e552db94588455c081efd87dbde0cd96d02942Ian Rogers << PrettyDescriptor(referrer) << "'"; 17162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str()); 17287e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 17387e552db94588455c081efd87dbde0cd96d02942Ian Rogers 174ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromvoid ThrowIllegalAccessErrorField(mirror::Class* referrer, mirror::ArtField* accessed) { 17587e552db94588455c081efd87dbde0cd96d02942Ian Rogers std::ostringstream msg; 17687e552db94588455c081efd87dbde0cd96d02942Ian Rogers msg << "Field '" << PrettyField(accessed, false) << "' is inaccessible to class '" 17787e552db94588455c081efd87dbde0cd96d02942Ian Rogers << PrettyDescriptor(referrer) << "'"; 17862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str()); 17987e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 18087e552db94588455c081efd87dbde0cd96d02942Ian Rogers 181ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersvoid ThrowIllegalAccessErrorFinalField(mirror::ArtMethod* referrer, 182ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtField* accessed) { 18387e552db94588455c081efd87dbde0cd96d02942Ian Rogers std::ostringstream msg; 18487e552db94588455c081efd87dbde0cd96d02942Ian Rogers msg << "Final field '" << PrettyField(accessed, false) << "' cannot be written to by method '" 18587e552db94588455c081efd87dbde0cd96d02942Ian Rogers << PrettyMethod(referrer) << "'"; 186ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ThrowException(NULL, "Ljava/lang/IllegalAccessError;", 187ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom referrer != NULL ? referrer->GetClass() : NULL, 18862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers msg.str().c_str()); 18962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 19062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 1912ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid ThrowIllegalAccessError(mirror::Class* referrer, const char* fmt, ...) { 19262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_list args; 19362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_start(args, fmt); 19462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/IllegalAccessError;", referrer, fmt, &args); 19562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_end(args); 19687e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 19787e552db94588455c081efd87dbde0cd96d02942Ian Rogers 19811d5d8fffe41cc7daadbfa2ca98ecb978f3029afJeff Hao// IllegalAccessException 19911d5d8fffe41cc7daadbfa2ca98ecb978f3029afJeff Hao 20011d5d8fffe41cc7daadbfa2ca98ecb978f3029afJeff Haovoid ThrowIllegalAccessException(const ThrowLocation* throw_location, const char* msg) { 20111d5d8fffe41cc7daadbfa2ca98ecb978f3029afJeff Hao ThrowException(throw_location, "Ljava/lang/IllegalAccessException;", NULL, msg); 20211d5d8fffe41cc7daadbfa2ca98ecb978f3029afJeff Hao} 20311d5d8fffe41cc7daadbfa2ca98ecb978f3029afJeff Hao 20462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// IllegalArgumentException 20562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 20662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowIllegalArgumentException(const ThrowLocation* throw_location, const char* msg) { 20762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(throw_location, "Ljava/lang/IllegalArgumentException;", NULL, msg); 20862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 20962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 21062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 21187e552db94588455c081efd87dbde0cd96d02942Ian Rogers// IncompatibleClassChangeError 21287e552db94588455c081efd87dbde0cd96d02942Ian Rogers 21387e552db94588455c081efd87dbde0cd96d02942Ian Rogersvoid ThrowIncompatibleClassChangeError(InvokeType expected_type, InvokeType found_type, 214ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtMethod* method, 215ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers mirror::ArtMethod* referrer) { 21687e552db94588455c081efd87dbde0cd96d02942Ian Rogers std::ostringstream msg; 21787e552db94588455c081efd87dbde0cd96d02942Ian Rogers msg << "The method '" << PrettyMethod(method) << "' was expected to be of type " 21887e552db94588455c081efd87dbde0cd96d02942Ian Rogers << expected_type << " but instead was found to be of type " << found_type; 21962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/IncompatibleClassChangeError;", 22062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers referrer != NULL ? referrer->GetClass() : NULL, 22162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers msg.str().c_str()); 22287e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 22387e552db94588455c081efd87dbde0cd96d02942Ian Rogers 224ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersvoid ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(mirror::ArtMethod* interface_method, 2252dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Object* this_object, 226ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers mirror::ArtMethod* referrer) { 22787e552db94588455c081efd87dbde0cd96d02942Ian Rogers // Referrer is calling interface_method on this_object, however, the interface_method isn't 22887e552db94588455c081efd87dbde0cd96d02942Ian Rogers // implemented by this_object. 22987e552db94588455c081efd87dbde0cd96d02942Ian Rogers CHECK(this_object != NULL); 23087e552db94588455c081efd87dbde0cd96d02942Ian Rogers std::ostringstream msg; 23187e552db94588455c081efd87dbde0cd96d02942Ian Rogers msg << "Class '" << PrettyDescriptor(this_object->GetClass()) 23287e552db94588455c081efd87dbde0cd96d02942Ian Rogers << "' does not implement interface '" 23387e552db94588455c081efd87dbde0cd96d02942Ian Rogers << PrettyDescriptor(interface_method->GetDeclaringClass()) 23487e552db94588455c081efd87dbde0cd96d02942Ian Rogers << "' in call to '" << PrettyMethod(interface_method) << "'"; 23562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/IncompatibleClassChangeError;", 23662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers referrer != NULL ? referrer->GetClass() : NULL, 23762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers msg.str().c_str()); 23887e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 23987e552db94588455c081efd87dbde0cd96d02942Ian Rogers 240ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersvoid ThrowIncompatibleClassChangeErrorField(mirror::ArtField* resolved_field, bool is_static, 241ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers mirror::ArtMethod* referrer) { 24287e552db94588455c081efd87dbde0cd96d02942Ian Rogers std::ostringstream msg; 24387e552db94588455c081efd87dbde0cd96d02942Ian Rogers msg << "Expected '" << PrettyField(resolved_field) << "' to be a " 244b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers << (is_static ? "static" : "instance") << " field" << " rather than a " 245b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers << (is_static ? "instance" : "static") << " field"; 24662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/IncompatibleClassChangeError;", referrer->GetClass(), 24762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers msg.str().c_str()); 24862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 24962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 250ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersvoid ThrowIncompatibleClassChangeError(mirror::Class* referrer, const char* fmt, ...) { 25162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_list args; 25262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_start(args, fmt); 25362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/IncompatibleClassChangeError;", referrer, fmt, &args); 25462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_end(args); 25562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 25662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 2578d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers// IOException 2588d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 2598d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogersvoid ThrowIOException(const char* fmt, ...) { 2608d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers va_list args; 2618d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers va_start(args, fmt); 2628d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers ThrowException(NULL, "Ljava/io/IOException;", NULL, fmt, &args); 2638d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers va_end(args); 2648d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers} 2658d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 266329d18806792771dfee064203fe27875d79cd53aAndreas Gampevoid ThrowWrappedIOException(const char* fmt, ...) { 267329d18806792771dfee064203fe27875d79cd53aAndreas Gampe va_list args; 268329d18806792771dfee064203fe27875d79cd53aAndreas Gampe va_start(args, fmt); 269329d18806792771dfee064203fe27875d79cd53aAndreas Gampe ThrowWrappedException(NULL, "Ljava/io/IOException;", NULL, fmt, &args); 270329d18806792771dfee064203fe27875d79cd53aAndreas Gampe va_end(args); 271329d18806792771dfee064203fe27875d79cd53aAndreas Gampe} 272329d18806792771dfee064203fe27875d79cd53aAndreas Gampe 27362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// LinkageError 27462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 275ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersvoid ThrowLinkageError(mirror::Class* referrer, const char* fmt, ...) { 27662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_list args; 27762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_start(args, fmt); 27862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/LinkageError;", referrer, fmt, &args); 27962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_end(args); 28062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 28162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 28262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// NegativeArraySizeException 28362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 28462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowNegativeArraySizeException(int size) { 285ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ThrowException(NULL, "Ljava/lang/NegativeArraySizeException;", NULL, 286ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom StringPrintf("%d", size).c_str()); 28762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 28862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 28962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowNegativeArraySizeException(const char* msg) { 29062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/NegativeArraySizeException;", NULL, msg); 29162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 29262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 29362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// NoSuchFieldError 29462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 29562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowNoSuchFieldError(const StringPiece& scope, mirror::Class* c, 29662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const StringPiece& type, const StringPiece& name) 29762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 29862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers std::ostringstream msg; 299cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers std::string temp; 30062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers msg << "No " << scope << "field " << name << " of type " << type 301cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers << " in class " << c->GetDescriptor(&temp) << " or its superclasses"; 30262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/NoSuchFieldError;", c, msg.str().c_str()); 30387e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 30487e552db94588455c081efd87dbde0cd96d02942Ian Rogers 30587e552db94588455c081efd87dbde0cd96d02942Ian Rogers// NoSuchMethodError 30687e552db94588455c081efd87dbde0cd96d02942Ian Rogers 3072dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid ThrowNoSuchMethodError(InvokeType type, mirror::Class* c, const StringPiece& name, 308d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers const Signature& signature) { 30987e552db94588455c081efd87dbde0cd96d02942Ian Rogers std::ostringstream msg; 310cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers std::string temp; 31187e552db94588455c081efd87dbde0cd96d02942Ian Rogers msg << "No " << type << " method " << name << signature 312cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers << " in class " << c->GetDescriptor(&temp) << " or its super classes"; 31362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/NoSuchMethodError;", c, msg.str().c_str()); 31487e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 31587e552db94588455c081efd87dbde0cd96d02942Ian Rogers 31662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowNoSuchMethodError(uint32_t method_idx) { 31762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers Thread* self = Thread::Current(); 31862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 31962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mirror::DexCache* dex_cache = throw_location.GetMethod()->GetDeclaringClass()->GetDexCache(); 3204445a7e3398a6143939168097a3aa275b734504dIan Rogers const DexFile& dex_file = *dex_cache->GetDexFile(); 32187e552db94588455c081efd87dbde0cd96d02942Ian Rogers std::ostringstream msg; 32287e552db94588455c081efd87dbde0cd96d02942Ian Rogers msg << "No method '" << PrettyMethod(method_idx, dex_file, true) << "'"; 32362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(&throw_location, "Ljava/lang/NoSuchMethodError;", 32462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers throw_location.GetMethod()->GetDeclaringClass(), msg.str().c_str()); 32562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 32662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 32762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// NullPointerException 32862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 32962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowNullPointerExceptionForFieldAccess(const ThrowLocation& throw_location, 330ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtField* field, bool is_read) { 33162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers std::ostringstream msg; 33262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers msg << "Attempt to " << (is_read ? "read from" : "write to") 33362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers << " field '" << PrettyField(field, true) << "' on a null object reference"; 33462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL, msg.str().c_str()); 33562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 33662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 3372d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertzstatic void ThrowNullPointerExceptionForMethodAccessImpl(const ThrowLocation& throw_location, 3382d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz uint32_t method_idx, 3392d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz const DexFile& dex_file, 3402d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz InvokeType type) 3412d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 34262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers std::ostringstream msg; 34362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers msg << "Attempt to invoke " << type << " method '" 34462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers << PrettyMethod(method_idx, dex_file, true) << "' on a null object reference"; 34562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL, msg.str().c_str()); 34662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 34762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 348ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromvoid ThrowNullPointerExceptionForMethodAccess(const ThrowLocation& throw_location, 349ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom uint32_t method_idx, 3502d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz InvokeType type) { 3512d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz mirror::DexCache* dex_cache = throw_location.GetMethod()->GetDeclaringClass()->GetDexCache(); 3522d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz const DexFile& dex_file = *dex_cache->GetDexFile(); 3532d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz ThrowNullPointerExceptionForMethodAccessImpl(throw_location, method_idx, 3542d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz dex_file, type); 3552d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz} 3562d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz 3572d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertzvoid ThrowNullPointerExceptionForMethodAccess(const ThrowLocation& throw_location, 358ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtMethod* method, 3592d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz InvokeType type) { 3602d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache(); 3612d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz const DexFile& dex_file = *dex_cache->GetDexFile(); 3622d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz ThrowNullPointerExceptionForMethodAccessImpl(throw_location, method->GetDexMethodIndex(), 3632d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz dex_file, type); 3642d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz} 3652d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz 36662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowNullPointerExceptionFromDexPC(const ThrowLocation& throw_location) { 367bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier const DexFile::CodeItem* code = throw_location.GetMethod()->GetCodeItem(); 36862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers uint32_t throw_dex_pc = throw_location.GetDexPc(); 36962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers CHECK_LT(throw_dex_pc, code->insns_size_in_code_units_); 37062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const Instruction* instr = Instruction::At(&code->insns_[throw_dex_pc]); 37162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers switch (instr->Opcode()) { 37262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::INVOKE_DIRECT: 37375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_35c(), kDirect); 37475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz break; 37562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::INVOKE_DIRECT_RANGE: 37675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_3rc(), kDirect); 37762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers break; 37862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::INVOKE_VIRTUAL: 37975b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_35c(), kVirtual); 38075b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz break; 38162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::INVOKE_VIRTUAL_RANGE: 38275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_3rc(), kVirtual); 38362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers break; 38462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::INVOKE_INTERFACE: 38575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_35c(), kInterface); 38675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz break; 38762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::INVOKE_INTERFACE_RANGE: 38875b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_3rc(), kInterface); 38962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers break; 3902d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz case Instruction::INVOKE_VIRTUAL_QUICK: 3912d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: { 3922d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // Since we replaced the method index, we ask the verifier to tell us which 3932d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // method is invoked at this location. 394ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtMethod* method = 3952d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz verifier::MethodVerifier::FindInvokedMethodAtDexPc(throw_location.GetMethod(), 3962d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz throw_location.GetDexPc()); 3972d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz if (method != NULL) { 3982d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // NPE with precise message. 3992d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz ThrowNullPointerExceptionForMethodAccess(throw_location, method, kVirtual); 4002d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz } else { 4012d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // NPE with imprecise message. 4022d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz ThrowNullPointerException(&throw_location, 4032d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz "Attempt to invoke a virtual method on a null object reference"); 4042d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz } 4052d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz break; 4062d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz } 40762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IGET: 40862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IGET_WIDE: 40962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IGET_OBJECT: 41062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IGET_BOOLEAN: 41162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IGET_BYTE: 41262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IGET_CHAR: 41362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IGET_SHORT: { 414ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtField* field = 41575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz Runtime::Current()->GetClassLinker()->ResolveField(instr->VRegC_22c(), 41662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers throw_location.GetMethod(), false); 41762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowNullPointerExceptionForFieldAccess(throw_location, field, true /* read */); 41862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers break; 41962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 4202d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz case Instruction::IGET_QUICK: 4212d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz case Instruction::IGET_WIDE_QUICK: 4222d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz case Instruction::IGET_OBJECT_QUICK: { 4232d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // Since we replaced the field index, we ask the verifier to tell us which 4242d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // field is accessed at this location. 425ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtField* field = 4262d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz verifier::MethodVerifier::FindAccessedFieldAtDexPc(throw_location.GetMethod(), 4272d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz throw_location.GetDexPc()); 4282d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz if (field != NULL) { 4292d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // NPE with precise message. 4302d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz ThrowNullPointerExceptionForFieldAccess(throw_location, field, true /* read */); 4312d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz } else { 4322d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // NPE with imprecise message. 4332d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz ThrowNullPointerException(&throw_location, 4342d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz "Attempt to read from a field on a null object reference"); 4352d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz } 4362d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz break; 4372d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz } 43862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IPUT: 43962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IPUT_WIDE: 44062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IPUT_OBJECT: 44162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IPUT_BOOLEAN: 44262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IPUT_BYTE: 44362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IPUT_CHAR: 44462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IPUT_SHORT: { 445ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtField* field = 44675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz Runtime::Current()->GetClassLinker()->ResolveField(instr->VRegC_22c(), 44762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers throw_location.GetMethod(), false); 44862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowNullPointerExceptionForFieldAccess(throw_location, field, false /* write */); 44962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers break; 45062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 4512d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz case Instruction::IPUT_QUICK: 4522d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz case Instruction::IPUT_WIDE_QUICK: 4532d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz case Instruction::IPUT_OBJECT_QUICK: { 4542d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // Since we replaced the field index, we ask the verifier to tell us which 4552d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // field is accessed at this location. 456ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtField* field = 4572d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz verifier::MethodVerifier::FindAccessedFieldAtDexPc(throw_location.GetMethod(), 4582d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz throw_location.GetDexPc()); 4592d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz if (field != NULL) { 4602d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // NPE with precise message. 4612d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz ThrowNullPointerExceptionForFieldAccess(throw_location, field, false /* write */); 4622d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz } else { 4632d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // NPE with imprecise message. 4642d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz ThrowNullPointerException(&throw_location, 4652d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz "Attempt to write to a field on a null object reference"); 4662d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz } 4672d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz break; 4682d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz } 46962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::AGET: 47062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::AGET_WIDE: 47162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::AGET_OBJECT: 47262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::AGET_BOOLEAN: 47362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::AGET_BYTE: 47462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::AGET_CHAR: 47562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::AGET_SHORT: 47662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL, 47762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers "Attempt to read from null array"); 47862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers break; 47962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::APUT: 48062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::APUT_WIDE: 48162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::APUT_OBJECT: 48262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::APUT_BOOLEAN: 48362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::APUT_BYTE: 48462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::APUT_CHAR: 48562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::APUT_SHORT: 48662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL, 48762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers "Attempt to write to null array"); 48862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers break; 48962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::ARRAY_LENGTH: 49062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL, 49162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers "Attempt to get length of null array"); 49262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers break; 49362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers default: { 49462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // TODO: We should have covered all the cases where we expect a NPE above, this 49562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // message/logging is so we can improve any cases we've missed in the future. 49662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const DexFile& dex_file = 49762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers *throw_location.GetMethod()->GetDeclaringClass()->GetDexCache()->GetDexFile(); 49862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL, 49962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers StringPrintf("Null pointer exception during instruction '%s'", 50062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers instr->DumpString(&dex_file).c_str()).c_str()); 50162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers break; 50262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 50362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 50462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 50562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 50662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowNullPointerException(const ThrowLocation* throw_location, const char* msg) { 50762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(throw_location, "Ljava/lang/NullPointerException;", NULL, msg); 50862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 50962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 51062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// RuntimeException 51162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 51262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowRuntimeException(const char* fmt, ...) { 51362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_list args; 51462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_start(args, fmt); 51562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/RuntimeException;", NULL, fmt, &args); 51662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_end(args); 51762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 51862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 51962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// VerifyError 52062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 521ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersvoid ThrowVerifyError(mirror::Class* referrer, const char* fmt, ...) { 52262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_list args; 52362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_start(args, fmt); 52462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/VerifyError;", referrer, fmt, &args); 52562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_end(args); 52687e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 52787e552db94588455c081efd87dbde0cd96d02942Ian Rogers 52887e552db94588455c081efd87dbde0cd96d02942Ian Rogers} // namespace art 529