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 1907ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "base/logging.h" 202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "class_linker-inl.h" 214f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h" 2275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz#include "dex_instruction-inl.h" 2387e552db94588455c081efd87dbde0cd96d02942Ian Rogers#include "invoke_type.h" 24ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include "mirror/art_method-inl.h" 254f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "mirror/class-inl.h" 262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object-inl.h" 272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object_array-inl.h" 2887e552db94588455c081efd87dbde0cd96d02942Ian Rogers#include "object_utils.h" 2987e552db94588455c081efd87dbde0cd96d02942Ian Rogers#include "thread.h" 302d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz#include "verifier/method_verifier.h" 3187e552db94588455c081efd87dbde0cd96d02942Ian Rogers 3287e552db94588455c081efd87dbde0cd96d02942Ian Rogers#include <sstream> 3387e552db94588455c081efd87dbde0cd96d02942Ian Rogers 3487e552db94588455c081efd87dbde0cd96d02942Ian Rogersnamespace art { 3587e552db94588455c081efd87dbde0cd96d02942Ian Rogers 3662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersstatic void AddReferrerLocation(std::ostream& os, const mirror::Class* referrer) 37b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 3887e552db94588455c081efd87dbde0cd96d02942Ian Rogers if (referrer != NULL) { 3962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ClassHelper kh(referrer); 4087e552db94588455c081efd87dbde0cd96d02942Ian Rogers std::string location(kh.GetLocation()); 4187e552db94588455c081efd87dbde0cd96d02942Ian Rogers if (!location.empty()) { 4262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers os << " (declaration of '" << PrettyDescriptor(referrer) 4362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers << "' appears in " << location << ")"; 4487e552db94588455c081efd87dbde0cd96d02942Ian Rogers } 4587e552db94588455c081efd87dbde0cd96d02942Ian Rogers } 4687e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 4787e552db94588455c081efd87dbde0cd96d02942Ian Rogers 4862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersstatic void ThrowException(const ThrowLocation* throw_location, const char* exception_descriptor, 4962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const mirror::Class* referrer, const char* fmt, va_list* args = NULL) 50b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 5162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers std::ostringstream msg; 5262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (args != NULL) { 5362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers std::string vmsg; 5462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers StringAppendV(&vmsg, fmt, *args); 5562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers msg << vmsg; 5662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } else { 5762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers msg << fmt; 5862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 5962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers AddReferrerLocation(msg, referrer); 6062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers Thread* self = Thread::Current(); 6162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (throw_location == NULL) { 6262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation computed_throw_location = self->GetCurrentLocationForThrow(); 6362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers self->ThrowNewException(computed_throw_location, exception_descriptor, msg.str().c_str()); 6462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } else { 6562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers self->ThrowNewException(*throw_location, exception_descriptor, msg.str().c_str()); 6687e552db94588455c081efd87dbde0cd96d02942Ian Rogers } 6787e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 6887e552db94588455c081efd87dbde0cd96d02942Ian Rogers 6956adf601ed9d1d11a2c462caa262e7de66a9e172Sebastien Hertz// AbstractMethodError 7056adf601ed9d1d11a2c462caa262e7de66a9e172Sebastien Hertz 71ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromvoid ThrowAbstractMethodError(const mirror::ArtMethod* method) { 7256adf601ed9d1d11a2c462caa262e7de66a9e172Sebastien Hertz ThrowException(NULL, "Ljava/lang/AbstractMethodError;", NULL, 7356adf601ed9d1d11a2c462caa262e7de66a9e172Sebastien Hertz StringPrintf("abstract method \"%s\"", 7456adf601ed9d1d11a2c462caa262e7de66a9e172Sebastien Hertz PrettyMethod(method).c_str()).c_str()); 7556adf601ed9d1d11a2c462caa262e7de66a9e172Sebastien Hertz} 7656adf601ed9d1d11a2c462caa262e7de66a9e172Sebastien Hertz 7762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// ArithmeticException 7887e552db94588455c081efd87dbde0cd96d02942Ian Rogers 790a3b863fb1acae912b54f4be2c1928d3afa5e936Sebastien Hertzvoid ThrowArithmeticExceptionDivideByZero() { 8062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/ArithmeticException;", NULL, "divide by zero"); 8187e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 8287e552db94588455c081efd87dbde0cd96d02942Ian Rogers 8362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// ArrayIndexOutOfBoundsException 8462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 8562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowArrayIndexOutOfBoundsException(int index, int length) { 8662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/ArrayIndexOutOfBoundsException;", NULL, 8762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers StringPrintf("length=%d; index=%d", length, index).c_str()); 8887e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 8987e552db94588455c081efd87dbde0cd96d02942Ian Rogers 9062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// ArrayStoreException 9162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 9262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowArrayStoreException(const mirror::Class* element_class, 9362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const mirror::Class* array_class) { 9462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/ArrayStoreException;", NULL, 9562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers StringPrintf("%s cannot be stored in an array of type %s", 9662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PrettyDescriptor(element_class).c_str(), 9762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PrettyDescriptor(array_class).c_str()).c_str()); 9862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 9962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 10062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// ClassCastException 10162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 10262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowClassCastException(const mirror::Class* dest_type, const mirror::Class* src_type) { 10362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/ClassCastException;", NULL, 10462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers StringPrintf("%s cannot be cast to %s", 10562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PrettyDescriptor(src_type).c_str(), 10662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PrettyDescriptor(dest_type).c_str()).c_str()); 10762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 10862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 10962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowClassCastException(const ThrowLocation* throw_location, const char* msg) { 11062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(throw_location, "Ljava/lang/ClassCastException;", NULL, msg); 11162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 11262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 11362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// ClassCircularityError 11462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 11562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowClassCircularityError(mirror::Class* c) { 11662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers std::ostringstream msg; 11762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers msg << PrettyDescriptor(c); 11862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/ClassCircularityError;", c, msg.str().c_str()); 11987e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 12087e552db94588455c081efd87dbde0cd96d02942Ian Rogers 12162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// ClassFormatError 12262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 12362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowClassFormatError(const mirror::Class* referrer, const char* fmt, ...) { 12462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_list args; 12562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_start(args, fmt); 12662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/ClassFormatError;", referrer, fmt, &args); 12762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_end(args);} 12862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 12987e552db94588455c081efd87dbde0cd96d02942Ian Rogers// IllegalAccessError 13087e552db94588455c081efd87dbde0cd96d02942Ian Rogers 1312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid ThrowIllegalAccessErrorClass(mirror::Class* referrer, mirror::Class* accessed) { 13287e552db94588455c081efd87dbde0cd96d02942Ian Rogers std::ostringstream msg; 133b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers msg << "Illegal class access: '" << PrettyDescriptor(referrer) << "' attempting to access '" 13487e552db94588455c081efd87dbde0cd96d02942Ian Rogers << PrettyDescriptor(accessed) << "'"; 13562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str()); 13687e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 13787e552db94588455c081efd87dbde0cd96d02942Ian Rogers 1382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid ThrowIllegalAccessErrorClassForMethodDispatch(mirror::Class* referrer, mirror::Class* accessed, 139ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom const mirror::ArtMethod* caller, 140ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom const mirror::ArtMethod* called, 14187e552db94588455c081efd87dbde0cd96d02942Ian Rogers InvokeType type) { 14287e552db94588455c081efd87dbde0cd96d02942Ian Rogers std::ostringstream msg; 143b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers msg << "Illegal class access ('" << PrettyDescriptor(referrer) << "' attempting to access '" 144b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers << PrettyDescriptor(accessed) << "') in attempt to invoke " << type 14587e552db94588455c081efd87dbde0cd96d02942Ian Rogers << " method " << PrettyMethod(called).c_str(); 14662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str()); 14787e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 14887e552db94588455c081efd87dbde0cd96d02942Ian Rogers 149ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromvoid ThrowIllegalAccessErrorMethod(mirror::Class* referrer, mirror::ArtMethod* accessed) { 15087e552db94588455c081efd87dbde0cd96d02942Ian Rogers std::ostringstream msg; 15187e552db94588455c081efd87dbde0cd96d02942Ian Rogers msg << "Method '" << PrettyMethod(accessed) << "' is inaccessible to class '" 15287e552db94588455c081efd87dbde0cd96d02942Ian Rogers << PrettyDescriptor(referrer) << "'"; 15362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str()); 15487e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 15587e552db94588455c081efd87dbde0cd96d02942Ian Rogers 156ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromvoid ThrowIllegalAccessErrorField(mirror::Class* referrer, mirror::ArtField* accessed) { 15787e552db94588455c081efd87dbde0cd96d02942Ian Rogers std::ostringstream msg; 15887e552db94588455c081efd87dbde0cd96d02942Ian Rogers msg << "Field '" << PrettyField(accessed, false) << "' is inaccessible to class '" 15987e552db94588455c081efd87dbde0cd96d02942Ian Rogers << PrettyDescriptor(referrer) << "'"; 16062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str()); 16187e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 16287e552db94588455c081efd87dbde0cd96d02942Ian Rogers 163ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromvoid ThrowIllegalAccessErrorFinalField(const mirror::ArtMethod* referrer, 164ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtField* accessed) { 16587e552db94588455c081efd87dbde0cd96d02942Ian Rogers std::ostringstream msg; 16687e552db94588455c081efd87dbde0cd96d02942Ian Rogers msg << "Final field '" << PrettyField(accessed, false) << "' cannot be written to by method '" 16787e552db94588455c081efd87dbde0cd96d02942Ian Rogers << PrettyMethod(referrer) << "'"; 168ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ThrowException(NULL, "Ljava/lang/IllegalAccessError;", 169ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom referrer != NULL ? referrer->GetClass() : NULL, 17062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers msg.str().c_str()); 17162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 17262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 1732ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid ThrowIllegalAccessError(mirror::Class* referrer, const char* fmt, ...) { 17462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_list args; 17562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_start(args, fmt); 17662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/IllegalAccessError;", referrer, fmt, &args); 17762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_end(args); 17887e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 17987e552db94588455c081efd87dbde0cd96d02942Ian Rogers 18062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// IllegalArgumentException 18162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 18262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowIllegalArgumentException(const ThrowLocation* throw_location, const char* msg) { 18362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(throw_location, "Ljava/lang/IllegalArgumentException;", NULL, msg); 18462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 18562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 18662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 18787e552db94588455c081efd87dbde0cd96d02942Ian Rogers// IncompatibleClassChangeError 18887e552db94588455c081efd87dbde0cd96d02942Ian Rogers 18987e552db94588455c081efd87dbde0cd96d02942Ian Rogersvoid ThrowIncompatibleClassChangeError(InvokeType expected_type, InvokeType found_type, 190ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtMethod* method, 191ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom const mirror::ArtMethod* referrer) { 19287e552db94588455c081efd87dbde0cd96d02942Ian Rogers std::ostringstream msg; 19387e552db94588455c081efd87dbde0cd96d02942Ian Rogers msg << "The method '" << PrettyMethod(method) << "' was expected to be of type " 19487e552db94588455c081efd87dbde0cd96d02942Ian Rogers << expected_type << " but instead was found to be of type " << found_type; 19562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/IncompatibleClassChangeError;", 19662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers referrer != NULL ? referrer->GetClass() : NULL, 19762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers msg.str().c_str()); 19887e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 19987e552db94588455c081efd87dbde0cd96d02942Ian Rogers 200ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromvoid ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(const mirror::ArtMethod* interface_method, 2012dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Object* this_object, 202ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom const mirror::ArtMethod* referrer) { 20387e552db94588455c081efd87dbde0cd96d02942Ian Rogers // Referrer is calling interface_method on this_object, however, the interface_method isn't 20487e552db94588455c081efd87dbde0cd96d02942Ian Rogers // implemented by this_object. 20587e552db94588455c081efd87dbde0cd96d02942Ian Rogers CHECK(this_object != NULL); 20687e552db94588455c081efd87dbde0cd96d02942Ian Rogers std::ostringstream msg; 20787e552db94588455c081efd87dbde0cd96d02942Ian Rogers msg << "Class '" << PrettyDescriptor(this_object->GetClass()) 20887e552db94588455c081efd87dbde0cd96d02942Ian Rogers << "' does not implement interface '" 20987e552db94588455c081efd87dbde0cd96d02942Ian Rogers << PrettyDescriptor(interface_method->GetDeclaringClass()) 21087e552db94588455c081efd87dbde0cd96d02942Ian Rogers << "' in call to '" << PrettyMethod(interface_method) << "'"; 21162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/IncompatibleClassChangeError;", 21262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers referrer != NULL ? referrer->GetClass() : NULL, 21362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers msg.str().c_str()); 21487e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 21587e552db94588455c081efd87dbde0cd96d02942Ian Rogers 216ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromvoid ThrowIncompatibleClassChangeErrorField(const mirror::ArtField* resolved_field, bool is_static, 217ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom const mirror::ArtMethod* referrer) { 21887e552db94588455c081efd87dbde0cd96d02942Ian Rogers std::ostringstream msg; 21987e552db94588455c081efd87dbde0cd96d02942Ian Rogers msg << "Expected '" << PrettyField(resolved_field) << "' to be a " 220b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers << (is_static ? "static" : "instance") << " field" << " rather than a " 221b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers << (is_static ? "instance" : "static") << " field"; 22262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/IncompatibleClassChangeError;", referrer->GetClass(), 22362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers msg.str().c_str()); 22462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 22562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 2262ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid ThrowIncompatibleClassChangeError(const mirror::Class* referrer, const char* fmt, ...) { 22762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_list args; 22862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_start(args, fmt); 22962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/IncompatibleClassChangeError;", referrer, fmt, &args); 23062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_end(args); 23162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 23262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 23362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// LinkageError 23462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 23562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowLinkageError(const mirror::Class* referrer, const char* fmt, ...) { 23662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_list args; 23762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_start(args, fmt); 23862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/LinkageError;", referrer, fmt, &args); 23962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_end(args); 24062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 24162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 24262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// NegativeArraySizeException 24362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 24462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowNegativeArraySizeException(int size) { 245ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ThrowException(NULL, "Ljava/lang/NegativeArraySizeException;", NULL, 246ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom StringPrintf("%d", size).c_str()); 24762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 24862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 24962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowNegativeArraySizeException(const char* msg) { 25062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/NegativeArraySizeException;", NULL, msg); 25162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 25262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 25362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// NoSuchFieldError 25462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 25562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowNoSuchFieldError(const StringPiece& scope, mirror::Class* c, 25662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const StringPiece& type, const StringPiece& name) 25762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 25862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ClassHelper kh(c); 25962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers std::ostringstream msg; 26062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers msg << "No " << scope << "field " << name << " of type " << type 26162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers << " in class " << kh.GetDescriptor() << " or its superclasses"; 26262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/NoSuchFieldError;", c, msg.str().c_str()); 26387e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 26487e552db94588455c081efd87dbde0cd96d02942Ian Rogers 26587e552db94588455c081efd87dbde0cd96d02942Ian Rogers// NoSuchMethodError 26687e552db94588455c081efd87dbde0cd96d02942Ian Rogers 2672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid ThrowNoSuchMethodError(InvokeType type, mirror::Class* c, const StringPiece& name, 26862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const StringPiece& signature) { 26987e552db94588455c081efd87dbde0cd96d02942Ian Rogers std::ostringstream msg; 27087e552db94588455c081efd87dbde0cd96d02942Ian Rogers ClassHelper kh(c); 27187e552db94588455c081efd87dbde0cd96d02942Ian Rogers msg << "No " << type << " method " << name << signature 27287e552db94588455c081efd87dbde0cd96d02942Ian Rogers << " in class " << kh.GetDescriptor() << " or its super classes"; 27362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/NoSuchMethodError;", c, msg.str().c_str()); 27487e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 27587e552db94588455c081efd87dbde0cd96d02942Ian Rogers 27662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowNoSuchMethodError(uint32_t method_idx) { 27762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers Thread* self = Thread::Current(); 27862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 27962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mirror::DexCache* dex_cache = throw_location.GetMethod()->GetDeclaringClass()->GetDexCache(); 2804445a7e3398a6143939168097a3aa275b734504dIan Rogers const DexFile& dex_file = *dex_cache->GetDexFile(); 28187e552db94588455c081efd87dbde0cd96d02942Ian Rogers std::ostringstream msg; 28287e552db94588455c081efd87dbde0cd96d02942Ian Rogers msg << "No method '" << PrettyMethod(method_idx, dex_file, true) << "'"; 28362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(&throw_location, "Ljava/lang/NoSuchMethodError;", 28462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers throw_location.GetMethod()->GetDeclaringClass(), msg.str().c_str()); 28562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 28662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 28762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// NullPointerException 28862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 28962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowNullPointerExceptionForFieldAccess(const ThrowLocation& throw_location, 290ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtField* field, bool is_read) { 29162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers std::ostringstream msg; 29262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers msg << "Attempt to " << (is_read ? "read from" : "write to") 29362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers << " field '" << PrettyField(field, true) << "' on a null object reference"; 29462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL, msg.str().c_str()); 29562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 29662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 2972d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertzstatic void ThrowNullPointerExceptionForMethodAccessImpl(const ThrowLocation& throw_location, 2982d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz uint32_t method_idx, 2992d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz const DexFile& dex_file, 3002d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz InvokeType type) 3012d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 30262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers std::ostringstream msg; 30362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers msg << "Attempt to invoke " << type << " method '" 30462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers << PrettyMethod(method_idx, dex_file, true) << "' on a null object reference"; 30562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL, msg.str().c_str()); 30662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 30762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 308ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromvoid ThrowNullPointerExceptionForMethodAccess(const ThrowLocation& throw_location, 309ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom uint32_t method_idx, 3102d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz InvokeType type) { 3112d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz mirror::DexCache* dex_cache = throw_location.GetMethod()->GetDeclaringClass()->GetDexCache(); 3122d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz const DexFile& dex_file = *dex_cache->GetDexFile(); 3132d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz ThrowNullPointerExceptionForMethodAccessImpl(throw_location, method_idx, 3142d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz dex_file, type); 3152d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz} 3162d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz 3172d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertzvoid ThrowNullPointerExceptionForMethodAccess(const ThrowLocation& throw_location, 318ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtMethod* method, 3192d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz InvokeType type) { 3202d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache(); 3212d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz const DexFile& dex_file = *dex_cache->GetDexFile(); 3222d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz ThrowNullPointerExceptionForMethodAccessImpl(throw_location, method->GetDexMethodIndex(), 3232d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz dex_file, type); 3242d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz} 3252d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz 32662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowNullPointerExceptionFromDexPC(const ThrowLocation& throw_location) { 32762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const DexFile::CodeItem* code = MethodHelper(throw_location.GetMethod()).GetCodeItem(); 32862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers uint32_t throw_dex_pc = throw_location.GetDexPc(); 32962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers CHECK_LT(throw_dex_pc, code->insns_size_in_code_units_); 33062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const Instruction* instr = Instruction::At(&code->insns_[throw_dex_pc]); 33162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers switch (instr->Opcode()) { 33262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::INVOKE_DIRECT: 33375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_35c(), kDirect); 33475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz break; 33562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::INVOKE_DIRECT_RANGE: 33675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_3rc(), kDirect); 33762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers break; 33862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::INVOKE_VIRTUAL: 33975b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_35c(), kVirtual); 34075b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz break; 34162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::INVOKE_VIRTUAL_RANGE: 34275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_3rc(), kVirtual); 34362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers break; 34462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::INVOKE_INTERFACE: 34575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_35c(), kInterface); 34675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz break; 34762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::INVOKE_INTERFACE_RANGE: 34875b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_3rc(), kInterface); 34962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers break; 3502d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz case Instruction::INVOKE_VIRTUAL_QUICK: 3512d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: { 3522d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // Since we replaced the method index, we ask the verifier to tell us which 3532d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // method is invoked at this location. 354ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtMethod* method = 3552d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz verifier::MethodVerifier::FindInvokedMethodAtDexPc(throw_location.GetMethod(), 3562d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz throw_location.GetDexPc()); 3572d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz if (method != NULL) { 3582d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // NPE with precise message. 3592d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz ThrowNullPointerExceptionForMethodAccess(throw_location, method, kVirtual); 3602d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz } else { 3612d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // NPE with imprecise message. 3622d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz ThrowNullPointerException(&throw_location, 3632d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz "Attempt to invoke a virtual method on a null object reference"); 3642d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz } 3652d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz break; 3662d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz } 36762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IGET: 36862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IGET_WIDE: 36962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IGET_OBJECT: 37062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IGET_BOOLEAN: 37162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IGET_BYTE: 37262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IGET_CHAR: 37362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IGET_SHORT: { 374ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtField* field = 37575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz Runtime::Current()->GetClassLinker()->ResolveField(instr->VRegC_22c(), 37662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers throw_location.GetMethod(), false); 37762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowNullPointerExceptionForFieldAccess(throw_location, field, true /* read */); 37862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers break; 37962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 3802d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz case Instruction::IGET_QUICK: 3812d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz case Instruction::IGET_WIDE_QUICK: 3822d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz case Instruction::IGET_OBJECT_QUICK: { 3832d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // Since we replaced the field index, we ask the verifier to tell us which 3842d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // field is accessed at this location. 385ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtField* field = 3862d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz verifier::MethodVerifier::FindAccessedFieldAtDexPc(throw_location.GetMethod(), 3872d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz throw_location.GetDexPc()); 3882d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz if (field != NULL) { 3892d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // NPE with precise message. 3902d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz ThrowNullPointerExceptionForFieldAccess(throw_location, field, true /* read */); 3912d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz } else { 3922d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // NPE with imprecise message. 3932d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz ThrowNullPointerException(&throw_location, 3942d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz "Attempt to read from a field on a null object reference"); 3952d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz } 3962d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz break; 3972d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz } 39862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IPUT: 39962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IPUT_WIDE: 40062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IPUT_OBJECT: 40162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IPUT_BOOLEAN: 40262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IPUT_BYTE: 40362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IPUT_CHAR: 40462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::IPUT_SHORT: { 405ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtField* field = 40675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz Runtime::Current()->GetClassLinker()->ResolveField(instr->VRegC_22c(), 40762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers throw_location.GetMethod(), false); 40862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowNullPointerExceptionForFieldAccess(throw_location, field, false /* write */); 40962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers break; 41062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 4112d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz case Instruction::IPUT_QUICK: 4122d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz case Instruction::IPUT_WIDE_QUICK: 4132d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz case Instruction::IPUT_OBJECT_QUICK: { 4142d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // Since we replaced the field index, we ask the verifier to tell us which 4152d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // field is accessed at this location. 416ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtField* field = 4172d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz verifier::MethodVerifier::FindAccessedFieldAtDexPc(throw_location.GetMethod(), 4182d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz throw_location.GetDexPc()); 4192d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz if (field != NULL) { 4202d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // NPE with precise message. 4212d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz ThrowNullPointerExceptionForFieldAccess(throw_location, field, false /* write */); 4222d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz } else { 4232d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // NPE with imprecise message. 4242d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz ThrowNullPointerException(&throw_location, 4252d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz "Attempt to write to a field on a null object reference"); 4262d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz } 4272d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz break; 4282d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz } 42962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::AGET: 43062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::AGET_WIDE: 43162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::AGET_OBJECT: 43262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::AGET_BOOLEAN: 43362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::AGET_BYTE: 43462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::AGET_CHAR: 43562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::AGET_SHORT: 43662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL, 43762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers "Attempt to read from null array"); 43862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers break; 43962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::APUT: 44062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::APUT_WIDE: 44162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::APUT_OBJECT: 44262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::APUT_BOOLEAN: 44362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::APUT_BYTE: 44462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::APUT_CHAR: 44562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::APUT_SHORT: 44662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL, 44762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers "Attempt to write to null array"); 44862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers break; 44962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case Instruction::ARRAY_LENGTH: 45062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL, 45162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers "Attempt to get length of null array"); 45262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers break; 45362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers default: { 45462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // TODO: We should have covered all the cases where we expect a NPE above, this 45562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // message/logging is so we can improve any cases we've missed in the future. 45662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const DexFile& dex_file = 45762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers *throw_location.GetMethod()->GetDeclaringClass()->GetDexCache()->GetDexFile(); 45862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL, 45962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers StringPrintf("Null pointer exception during instruction '%s'", 46062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers instr->DumpString(&dex_file).c_str()).c_str()); 46162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers break; 46262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 46362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 46462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 46562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 46662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowNullPointerException(const ThrowLocation* throw_location, const char* msg) { 46762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(throw_location, "Ljava/lang/NullPointerException;", NULL, msg); 46862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 46962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 47062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// RuntimeException 47162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 47262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowRuntimeException(const char* fmt, ...) { 47362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_list args; 47462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_start(args, fmt); 47562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/RuntimeException;", NULL, fmt, &args); 47662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_end(args); 47762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 47862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 47962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// VerifyError 48062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 48162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid ThrowVerifyError(const mirror::Class* referrer, const char* fmt, ...) { 48262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_list args; 48362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_start(args, fmt); 48462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowException(NULL, "Ljava/lang/VerifyError;", referrer, fmt, &args); 48562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers va_end(args); 48687e552db94588455c081efd87dbde0cd96d02942Ian Rogers} 48787e552db94588455c081efd87dbde0cd96d02942Ian Rogers 48887e552db94588455c081efd87dbde0cd96d02942Ian Rogers} // namespace art 489