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