blob: f5b435400f15f239ad4cf739c22210547d330c60 [file] [log] [blame]
Ian Rogers87e552d2012-08-31 15:54:48 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "common_throws.h"
18
Ian Rogers22d5e732014-07-15 22:23:51 -070019#include <sstream>
20
Elliott Hughes07ed66b2012-12-12 18:34:25 -080021#include "base/logging.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080022#include "class_linker-inl.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070023#include "dex_file-inl.h"
Sebastien Hertz75b2a4a2013-05-21 09:25:10 +020024#include "dex_instruction-inl.h"
Ian Rogers87e552d2012-08-31 15:54:48 -070025#include "invoke_type.h"
Brian Carlstromea46f952013-07-30 01:26:50 -070026#include "mirror/art_method-inl.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070027#include "mirror/class-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080028#include "mirror/object-inl.h"
29#include "mirror/object_array-inl.h"
Ian Rogers87e552d2012-08-31 15:54:48 -070030#include "thread.h"
Sebastien Hertz2d6ba512013-05-17 11:31:37 +020031#include "verifier/method_verifier.h"
Ian Rogers87e552d2012-08-31 15:54:48 -070032
Ian Rogers87e552d2012-08-31 15:54:48 -070033namespace art {
34
Ian Rogersef7d42f2014-01-06 12:55:46 -080035static void AddReferrerLocation(std::ostream& os, mirror::Class* referrer)
Ian Rogersb726dcb2012-09-05 08:57:23 -070036 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers87e552d2012-08-31 15:54:48 -070037 if (referrer != NULL) {
Mathieu Chartierf8322842014-05-16 10:59:25 -070038 std::string location(referrer->GetLocation());
Ian Rogers87e552d2012-08-31 15:54:48 -070039 if (!location.empty()) {
40 os << " (declaration of '" << PrettyDescriptor(referrer)
41 << "' appears in " << location << ")";
42 }
43 }
44}
45
Ian Rogers62d6c772013-02-27 08:32:07 -080046static void ThrowException(const ThrowLocation* throw_location, const char* exception_descriptor,
Ian Rogersef7d42f2014-01-06 12:55:46 -080047 mirror::Class* referrer, const char* fmt, va_list* args = NULL)
Ian Rogers62d6c772013-02-27 08:32:07 -080048 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers87e552d2012-08-31 15:54:48 -070049 std::ostringstream msg;
Ian Rogers62d6c772013-02-27 08:32:07 -080050 if (args != NULL) {
51 std::string vmsg;
52 StringAppendV(&vmsg, fmt, *args);
53 msg << vmsg;
54 } else {
55 msg << fmt;
56 }
57 AddReferrerLocation(msg, referrer);
58 Thread* self = Thread::Current();
59 if (throw_location == NULL) {
60 ThrowLocation computed_throw_location = self->GetCurrentLocationForThrow();
61 self->ThrowNewException(computed_throw_location, exception_descriptor, msg.str().c_str());
62 } else {
63 self->ThrowNewException(*throw_location, exception_descriptor, msg.str().c_str());
Ian Rogers87e552d2012-08-31 15:54:48 -070064 }
65}
66
Andreas Gampe329d1882014-04-08 10:32:19 -070067static void ThrowWrappedException(const ThrowLocation* throw_location,
68 const char* exception_descriptor,
69 mirror::Class* referrer, const char* fmt, va_list* args = NULL)
70 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
71 std::ostringstream msg;
72 if (args != NULL) {
73 std::string vmsg;
74 StringAppendV(&vmsg, fmt, *args);
75 msg << vmsg;
76 } else {
77 msg << fmt;
78 }
79 AddReferrerLocation(msg, referrer);
80 Thread* self = Thread::Current();
81 if (throw_location == NULL) {
82 ThrowLocation computed_throw_location = self->GetCurrentLocationForThrow();
83 self->ThrowNewWrappedException(computed_throw_location, exception_descriptor, msg.str().c_str());
84 } else {
85 self->ThrowNewWrappedException(*throw_location, exception_descriptor, msg.str().c_str());
86 }
87}
88
Sebastien Hertz56adf602013-07-09 17:27:07 +020089// AbstractMethodError
90
Ian Rogersef7d42f2014-01-06 12:55:46 -080091void ThrowAbstractMethodError(mirror::ArtMethod* method) {
Sebastien Hertz56adf602013-07-09 17:27:07 +020092 ThrowException(NULL, "Ljava/lang/AbstractMethodError;", NULL,
93 StringPrintf("abstract method \"%s\"",
94 PrettyMethod(method).c_str()).c_str());
95}
96
Ian Rogers62d6c772013-02-27 08:32:07 -080097// ArithmeticException
98
Sebastien Hertz0a3b8632013-06-26 11:16:01 +020099void ThrowArithmeticExceptionDivideByZero() {
Ian Rogers62d6c772013-02-27 08:32:07 -0800100 ThrowException(NULL, "Ljava/lang/ArithmeticException;", NULL, "divide by zero");
101}
102
103// ArrayIndexOutOfBoundsException
104
105void ThrowArrayIndexOutOfBoundsException(int index, int length) {
106 ThrowException(NULL, "Ljava/lang/ArrayIndexOutOfBoundsException;", NULL,
107 StringPrintf("length=%d; index=%d", length, index).c_str());
108}
109
110// ArrayStoreException
111
Ian Rogersef7d42f2014-01-06 12:55:46 -0800112void ThrowArrayStoreException(mirror::Class* element_class, mirror::Class* array_class) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800113 ThrowException(NULL, "Ljava/lang/ArrayStoreException;", NULL,
114 StringPrintf("%s cannot be stored in an array of type %s",
115 PrettyDescriptor(element_class).c_str(),
116 PrettyDescriptor(array_class).c_str()).c_str());
117}
118
119// ClassCastException
120
Ian Rogersef7d42f2014-01-06 12:55:46 -0800121void ThrowClassCastException(mirror::Class* dest_type, mirror::Class* src_type) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800122 ThrowException(NULL, "Ljava/lang/ClassCastException;", NULL,
123 StringPrintf("%s cannot be cast to %s",
124 PrettyDescriptor(src_type).c_str(),
125 PrettyDescriptor(dest_type).c_str()).c_str());
126}
127
128void ThrowClassCastException(const ThrowLocation* throw_location, const char* msg) {
129 ThrowException(throw_location, "Ljava/lang/ClassCastException;", NULL, msg);
130}
131
132// ClassCircularityError
133
134void ThrowClassCircularityError(mirror::Class* c) {
135 std::ostringstream msg;
136 msg << PrettyDescriptor(c);
137 ThrowException(NULL, "Ljava/lang/ClassCircularityError;", c, msg.str().c_str());
138}
139
140// ClassFormatError
141
Ian Rogersef7d42f2014-01-06 12:55:46 -0800142void ThrowClassFormatError(mirror::Class* referrer, const char* fmt, ...) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800143 va_list args;
144 va_start(args, fmt);
145 ThrowException(NULL, "Ljava/lang/ClassFormatError;", referrer, fmt, &args);
146 va_end(args);}
147
Ian Rogers87e552d2012-08-31 15:54:48 -0700148// IllegalAccessError
149
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800150void ThrowIllegalAccessErrorClass(mirror::Class* referrer, mirror::Class* accessed) {
Ian Rogers87e552d2012-08-31 15:54:48 -0700151 std::ostringstream msg;
Ian Rogersb726dcb2012-09-05 08:57:23 -0700152 msg << "Illegal class access: '" << PrettyDescriptor(referrer) << "' attempting to access '"
Ian Rogers87e552d2012-08-31 15:54:48 -0700153 << PrettyDescriptor(accessed) << "'";
Ian Rogers62d6c772013-02-27 08:32:07 -0800154 ThrowException(NULL, "Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
Ian Rogers87e552d2012-08-31 15:54:48 -0700155}
156
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800157void ThrowIllegalAccessErrorClassForMethodDispatch(mirror::Class* referrer, mirror::Class* accessed,
Ian Rogersef7d42f2014-01-06 12:55:46 -0800158 mirror::ArtMethod* called,
Ian Rogers87e552d2012-08-31 15:54:48 -0700159 InvokeType type) {
160 std::ostringstream msg;
Ian Rogersb726dcb2012-09-05 08:57:23 -0700161 msg << "Illegal class access ('" << PrettyDescriptor(referrer) << "' attempting to access '"
162 << PrettyDescriptor(accessed) << "') in attempt to invoke " << type
Ian Rogers87e552d2012-08-31 15:54:48 -0700163 << " method " << PrettyMethod(called).c_str();
Ian Rogers62d6c772013-02-27 08:32:07 -0800164 ThrowException(NULL, "Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
Ian Rogers87e552d2012-08-31 15:54:48 -0700165}
166
Brian Carlstromea46f952013-07-30 01:26:50 -0700167void ThrowIllegalAccessErrorMethod(mirror::Class* referrer, mirror::ArtMethod* accessed) {
Ian Rogers87e552d2012-08-31 15:54:48 -0700168 std::ostringstream msg;
169 msg << "Method '" << PrettyMethod(accessed) << "' is inaccessible to class '"
170 << PrettyDescriptor(referrer) << "'";
Ian Rogers62d6c772013-02-27 08:32:07 -0800171 ThrowException(NULL, "Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
Ian Rogers87e552d2012-08-31 15:54:48 -0700172}
173
Brian Carlstromea46f952013-07-30 01:26:50 -0700174void ThrowIllegalAccessErrorField(mirror::Class* referrer, mirror::ArtField* accessed) {
Ian Rogers87e552d2012-08-31 15:54:48 -0700175 std::ostringstream msg;
176 msg << "Field '" << PrettyField(accessed, false) << "' is inaccessible to class '"
177 << PrettyDescriptor(referrer) << "'";
Ian Rogers62d6c772013-02-27 08:32:07 -0800178 ThrowException(NULL, "Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
Ian Rogers87e552d2012-08-31 15:54:48 -0700179}
180
Ian Rogersef7d42f2014-01-06 12:55:46 -0800181void ThrowIllegalAccessErrorFinalField(mirror::ArtMethod* referrer,
Brian Carlstromea46f952013-07-30 01:26:50 -0700182 mirror::ArtField* accessed) {
Ian Rogers87e552d2012-08-31 15:54:48 -0700183 std::ostringstream msg;
184 msg << "Final field '" << PrettyField(accessed, false) << "' cannot be written to by method '"
185 << PrettyMethod(referrer) << "'";
Brian Carlstromea46f952013-07-30 01:26:50 -0700186 ThrowException(NULL, "Ljava/lang/IllegalAccessError;",
187 referrer != NULL ? referrer->GetClass() : NULL,
Ian Rogers62d6c772013-02-27 08:32:07 -0800188 msg.str().c_str());
Ian Rogers87e552d2012-08-31 15:54:48 -0700189}
190
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700191void ThrowIllegalAccessError(mirror::Class* referrer, const char* fmt, ...) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800192 va_list args;
193 va_start(args, fmt);
194 ThrowException(NULL, "Ljava/lang/IllegalAccessError;", referrer, fmt, &args);
195 va_end(args);
196}
197
Jeff Hao11d5d8f2014-03-26 15:08:20 -0700198// IllegalAccessException
199
200void ThrowIllegalAccessException(const ThrowLocation* throw_location, const char* msg) {
201 ThrowException(throw_location, "Ljava/lang/IllegalAccessException;", NULL, msg);
202}
203
Ian Rogers62d6c772013-02-27 08:32:07 -0800204// IllegalArgumentException
205
206void ThrowIllegalArgumentException(const ThrowLocation* throw_location, const char* msg) {
207 ThrowException(throw_location, "Ljava/lang/IllegalArgumentException;", NULL, msg);
208}
209
210
Ian Rogers87e552d2012-08-31 15:54:48 -0700211// IncompatibleClassChangeError
212
213void ThrowIncompatibleClassChangeError(InvokeType expected_type, InvokeType found_type,
Brian Carlstromea46f952013-07-30 01:26:50 -0700214 mirror::ArtMethod* method,
Ian Rogersef7d42f2014-01-06 12:55:46 -0800215 mirror::ArtMethod* referrer) {
Ian Rogers87e552d2012-08-31 15:54:48 -0700216 std::ostringstream msg;
217 msg << "The method '" << PrettyMethod(method) << "' was expected to be of type "
218 << expected_type << " but instead was found to be of type " << found_type;
Ian Rogers62d6c772013-02-27 08:32:07 -0800219 ThrowException(NULL, "Ljava/lang/IncompatibleClassChangeError;",
220 referrer != NULL ? referrer->GetClass() : NULL,
221 msg.str().c_str());
Ian Rogers87e552d2012-08-31 15:54:48 -0700222}
223
Ian Rogersef7d42f2014-01-06 12:55:46 -0800224void ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(mirror::ArtMethod* interface_method,
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800225 mirror::Object* this_object,
Ian Rogersef7d42f2014-01-06 12:55:46 -0800226 mirror::ArtMethod* referrer) {
Ian Rogers87e552d2012-08-31 15:54:48 -0700227 // Referrer is calling interface_method on this_object, however, the interface_method isn't
228 // implemented by this_object.
229 CHECK(this_object != NULL);
230 std::ostringstream msg;
231 msg << "Class '" << PrettyDescriptor(this_object->GetClass())
232 << "' does not implement interface '"
233 << PrettyDescriptor(interface_method->GetDeclaringClass())
234 << "' in call to '" << PrettyMethod(interface_method) << "'";
Ian Rogers62d6c772013-02-27 08:32:07 -0800235 ThrowException(NULL, "Ljava/lang/IncompatibleClassChangeError;",
236 referrer != NULL ? referrer->GetClass() : NULL,
237 msg.str().c_str());
Ian Rogers87e552d2012-08-31 15:54:48 -0700238}
239
Ian Rogersef7d42f2014-01-06 12:55:46 -0800240void ThrowIncompatibleClassChangeErrorField(mirror::ArtField* resolved_field, bool is_static,
241 mirror::ArtMethod* referrer) {
Ian Rogers87e552d2012-08-31 15:54:48 -0700242 std::ostringstream msg;
243 msg << "Expected '" << PrettyField(resolved_field) << "' to be a "
Ian Rogersb726dcb2012-09-05 08:57:23 -0700244 << (is_static ? "static" : "instance") << " field" << " rather than a "
245 << (is_static ? "instance" : "static") << " field";
Ian Rogers62d6c772013-02-27 08:32:07 -0800246 ThrowException(NULL, "Ljava/lang/IncompatibleClassChangeError;", referrer->GetClass(),
247 msg.str().c_str());
248}
249
Ian Rogersef7d42f2014-01-06 12:55:46 -0800250void ThrowIncompatibleClassChangeError(mirror::Class* referrer, const char* fmt, ...) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800251 va_list args;
252 va_start(args, fmt);
253 ThrowException(NULL, "Ljava/lang/IncompatibleClassChangeError;", referrer, fmt, &args);
254 va_end(args);
255}
256
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700257// IOException
258
259void ThrowIOException(const char* fmt, ...) {
260 va_list args;
261 va_start(args, fmt);
262 ThrowException(NULL, "Ljava/io/IOException;", NULL, fmt, &args);
263 va_end(args);
264}
265
Andreas Gampe329d1882014-04-08 10:32:19 -0700266void ThrowWrappedIOException(const char* fmt, ...) {
267 va_list args;
268 va_start(args, fmt);
269 ThrowWrappedException(NULL, "Ljava/io/IOException;", NULL, fmt, &args);
270 va_end(args);
271}
272
Ian Rogers62d6c772013-02-27 08:32:07 -0800273// LinkageError
274
Ian Rogersef7d42f2014-01-06 12:55:46 -0800275void ThrowLinkageError(mirror::Class* referrer, const char* fmt, ...) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800276 va_list args;
277 va_start(args, fmt);
278 ThrowException(NULL, "Ljava/lang/LinkageError;", referrer, fmt, &args);
279 va_end(args);
280}
281
282// NegativeArraySizeException
283
284void ThrowNegativeArraySizeException(int size) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700285 ThrowException(NULL, "Ljava/lang/NegativeArraySizeException;", NULL,
286 StringPrintf("%d", size).c_str());
Ian Rogers62d6c772013-02-27 08:32:07 -0800287}
288
289void ThrowNegativeArraySizeException(const char* msg) {
290 ThrowException(NULL, "Ljava/lang/NegativeArraySizeException;", NULL, msg);
291}
292
293// NoSuchFieldError
294
295void ThrowNoSuchFieldError(const StringPiece& scope, mirror::Class* c,
296 const StringPiece& type, const StringPiece& name)
297 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800298 std::ostringstream msg;
Ian Rogers1ff3c982014-08-12 02:30:58 -0700299 std::string temp;
Ian Rogers62d6c772013-02-27 08:32:07 -0800300 msg << "No " << scope << "field " << name << " of type " << type
Ian Rogers1ff3c982014-08-12 02:30:58 -0700301 << " in class " << c->GetDescriptor(&temp) << " or its superclasses";
Ian Rogers62d6c772013-02-27 08:32:07 -0800302 ThrowException(NULL, "Ljava/lang/NoSuchFieldError;", c, msg.str().c_str());
Ian Rogers87e552d2012-08-31 15:54:48 -0700303}
304
305// NoSuchMethodError
306
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800307void ThrowNoSuchMethodError(InvokeType type, mirror::Class* c, const StringPiece& name,
Ian Rogersd91d6d62013-09-25 20:26:14 -0700308 const Signature& signature) {
Ian Rogers87e552d2012-08-31 15:54:48 -0700309 std::ostringstream msg;
Ian Rogers1ff3c982014-08-12 02:30:58 -0700310 std::string temp;
Ian Rogers87e552d2012-08-31 15:54:48 -0700311 msg << "No " << type << " method " << name << signature
Ian Rogers1ff3c982014-08-12 02:30:58 -0700312 << " in class " << c->GetDescriptor(&temp) << " or its super classes";
Ian Rogers62d6c772013-02-27 08:32:07 -0800313 ThrowException(NULL, "Ljava/lang/NoSuchMethodError;", c, msg.str().c_str());
Ian Rogers87e552d2012-08-31 15:54:48 -0700314}
315
Ian Rogers62d6c772013-02-27 08:32:07 -0800316void ThrowNoSuchMethodError(uint32_t method_idx) {
317 Thread* self = Thread::Current();
318 ThrowLocation throw_location = self->GetCurrentLocationForThrow();
319 mirror::DexCache* dex_cache = throw_location.GetMethod()->GetDeclaringClass()->GetDexCache();
Ian Rogers4445a7e2012-10-05 17:19:13 -0700320 const DexFile& dex_file = *dex_cache->GetDexFile();
Ian Rogers87e552d2012-08-31 15:54:48 -0700321 std::ostringstream msg;
322 msg << "No method '" << PrettyMethod(method_idx, dex_file, true) << "'";
Ian Rogers62d6c772013-02-27 08:32:07 -0800323 ThrowException(&throw_location, "Ljava/lang/NoSuchMethodError;",
324 throw_location.GetMethod()->GetDeclaringClass(), msg.str().c_str());
325}
326
327// NullPointerException
328
329void ThrowNullPointerExceptionForFieldAccess(const ThrowLocation& throw_location,
Brian Carlstromea46f952013-07-30 01:26:50 -0700330 mirror::ArtField* field, bool is_read) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800331 std::ostringstream msg;
332 msg << "Attempt to " << (is_read ? "read from" : "write to")
333 << " field '" << PrettyField(field, true) << "' on a null object reference";
334 ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL, msg.str().c_str());
335}
336
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200337static void ThrowNullPointerExceptionForMethodAccessImpl(const ThrowLocation& throw_location,
338 uint32_t method_idx,
339 const DexFile& dex_file,
340 InvokeType type)
341 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800342 std::ostringstream msg;
343 msg << "Attempt to invoke " << type << " method '"
344 << PrettyMethod(method_idx, dex_file, true) << "' on a null object reference";
345 ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL, msg.str().c_str());
346}
347
Brian Carlstromea46f952013-07-30 01:26:50 -0700348void ThrowNullPointerExceptionForMethodAccess(const ThrowLocation& throw_location,
349 uint32_t method_idx,
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200350 InvokeType type) {
351 mirror::DexCache* dex_cache = throw_location.GetMethod()->GetDeclaringClass()->GetDexCache();
352 const DexFile& dex_file = *dex_cache->GetDexFile();
353 ThrowNullPointerExceptionForMethodAccessImpl(throw_location, method_idx,
354 dex_file, type);
355}
356
357void ThrowNullPointerExceptionForMethodAccess(const ThrowLocation& throw_location,
Brian Carlstromea46f952013-07-30 01:26:50 -0700358 mirror::ArtMethod* method,
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200359 InvokeType type) {
360 mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
361 const DexFile& dex_file = *dex_cache->GetDexFile();
362 ThrowNullPointerExceptionForMethodAccessImpl(throw_location, method->GetDexMethodIndex(),
363 dex_file, type);
364}
365
Ian Rogers62d6c772013-02-27 08:32:07 -0800366void ThrowNullPointerExceptionFromDexPC(const ThrowLocation& throw_location) {
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700367 const DexFile::CodeItem* code = throw_location.GetMethod()->GetCodeItem();
Ian Rogers62d6c772013-02-27 08:32:07 -0800368 uint32_t throw_dex_pc = throw_location.GetDexPc();
369 CHECK_LT(throw_dex_pc, code->insns_size_in_code_units_);
370 const Instruction* instr = Instruction::At(&code->insns_[throw_dex_pc]);
Ian Rogers62d6c772013-02-27 08:32:07 -0800371 switch (instr->Opcode()) {
372 case Instruction::INVOKE_DIRECT:
Sebastien Hertz75b2a4a2013-05-21 09:25:10 +0200373 ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_35c(), kDirect);
374 break;
Ian Rogers62d6c772013-02-27 08:32:07 -0800375 case Instruction::INVOKE_DIRECT_RANGE:
Sebastien Hertz75b2a4a2013-05-21 09:25:10 +0200376 ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_3rc(), kDirect);
Ian Rogers62d6c772013-02-27 08:32:07 -0800377 break;
378 case Instruction::INVOKE_VIRTUAL:
Sebastien Hertz75b2a4a2013-05-21 09:25:10 +0200379 ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_35c(), kVirtual);
380 break;
Ian Rogers62d6c772013-02-27 08:32:07 -0800381 case Instruction::INVOKE_VIRTUAL_RANGE:
Sebastien Hertz75b2a4a2013-05-21 09:25:10 +0200382 ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_3rc(), kVirtual);
Ian Rogers62d6c772013-02-27 08:32:07 -0800383 break;
384 case Instruction::INVOKE_INTERFACE:
Sebastien Hertz75b2a4a2013-05-21 09:25:10 +0200385 ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_35c(), kInterface);
386 break;
Ian Rogers62d6c772013-02-27 08:32:07 -0800387 case Instruction::INVOKE_INTERFACE_RANGE:
Sebastien Hertz75b2a4a2013-05-21 09:25:10 +0200388 ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_3rc(), kInterface);
Ian Rogers62d6c772013-02-27 08:32:07 -0800389 break;
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200390 case Instruction::INVOKE_VIRTUAL_QUICK:
391 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
392 // Since we replaced the method index, we ask the verifier to tell us which
393 // method is invoked at this location.
Brian Carlstromea46f952013-07-30 01:26:50 -0700394 mirror::ArtMethod* method =
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200395 verifier::MethodVerifier::FindInvokedMethodAtDexPc(throw_location.GetMethod(),
396 throw_location.GetDexPc());
397 if (method != NULL) {
398 // NPE with precise message.
399 ThrowNullPointerExceptionForMethodAccess(throw_location, method, kVirtual);
400 } else {
401 // NPE with imprecise message.
402 ThrowNullPointerException(&throw_location,
403 "Attempt to invoke a virtual method on a null object reference");
404 }
405 break;
406 }
Ian Rogers62d6c772013-02-27 08:32:07 -0800407 case Instruction::IGET:
408 case Instruction::IGET_WIDE:
409 case Instruction::IGET_OBJECT:
410 case Instruction::IGET_BOOLEAN:
411 case Instruction::IGET_BYTE:
412 case Instruction::IGET_CHAR:
413 case Instruction::IGET_SHORT: {
Brian Carlstromea46f952013-07-30 01:26:50 -0700414 mirror::ArtField* field =
Sebastien Hertz75b2a4a2013-05-21 09:25:10 +0200415 Runtime::Current()->GetClassLinker()->ResolveField(instr->VRegC_22c(),
Ian Rogers62d6c772013-02-27 08:32:07 -0800416 throw_location.GetMethod(), false);
417 ThrowNullPointerExceptionForFieldAccess(throw_location, field, true /* read */);
418 break;
419 }
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200420 case Instruction::IGET_QUICK:
Mathieu Chartierffc605c2014-12-10 10:35:44 -0800421 case Instruction::IGET_BOOLEAN_QUICK:
422 case Instruction::IGET_BYTE_QUICK:
423 case Instruction::IGET_CHAR_QUICK:
424 case Instruction::IGET_SHORT_QUICK:
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200425 case Instruction::IGET_WIDE_QUICK:
426 case Instruction::IGET_OBJECT_QUICK: {
427 // Since we replaced the field index, we ask the verifier to tell us which
428 // field is accessed at this location.
Brian Carlstromea46f952013-07-30 01:26:50 -0700429 mirror::ArtField* field =
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200430 verifier::MethodVerifier::FindAccessedFieldAtDexPc(throw_location.GetMethod(),
431 throw_location.GetDexPc());
432 if (field != NULL) {
433 // NPE with precise message.
434 ThrowNullPointerExceptionForFieldAccess(throw_location, field, true /* read */);
435 } else {
436 // NPE with imprecise message.
437 ThrowNullPointerException(&throw_location,
438 "Attempt to read from a field on a null object reference");
439 }
440 break;
441 }
Ian Rogers62d6c772013-02-27 08:32:07 -0800442 case Instruction::IPUT:
443 case Instruction::IPUT_WIDE:
444 case Instruction::IPUT_OBJECT:
445 case Instruction::IPUT_BOOLEAN:
446 case Instruction::IPUT_BYTE:
447 case Instruction::IPUT_CHAR:
448 case Instruction::IPUT_SHORT: {
Brian Carlstromea46f952013-07-30 01:26:50 -0700449 mirror::ArtField* field =
Sebastien Hertz75b2a4a2013-05-21 09:25:10 +0200450 Runtime::Current()->GetClassLinker()->ResolveField(instr->VRegC_22c(),
Ian Rogers62d6c772013-02-27 08:32:07 -0800451 throw_location.GetMethod(), false);
452 ThrowNullPointerExceptionForFieldAccess(throw_location, field, false /* write */);
453 break;
454 }
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200455 case Instruction::IPUT_QUICK:
Fred Shih37f05ef2014-07-16 18:38:08 -0700456 case Instruction::IPUT_BOOLEAN_QUICK:
457 case Instruction::IPUT_BYTE_QUICK:
458 case Instruction::IPUT_CHAR_QUICK:
459 case Instruction::IPUT_SHORT_QUICK:
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200460 case Instruction::IPUT_WIDE_QUICK:
461 case Instruction::IPUT_OBJECT_QUICK: {
462 // Since we replaced the field index, we ask the verifier to tell us which
463 // field is accessed at this location.
Brian Carlstromea46f952013-07-30 01:26:50 -0700464 mirror::ArtField* field =
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200465 verifier::MethodVerifier::FindAccessedFieldAtDexPc(throw_location.GetMethod(),
466 throw_location.GetDexPc());
467 if (field != NULL) {
468 // NPE with precise message.
469 ThrowNullPointerExceptionForFieldAccess(throw_location, field, false /* write */);
470 } else {
471 // NPE with imprecise message.
472 ThrowNullPointerException(&throw_location,
473 "Attempt to write to a field on a null object reference");
474 }
475 break;
476 }
Ian Rogers62d6c772013-02-27 08:32:07 -0800477 case Instruction::AGET:
478 case Instruction::AGET_WIDE:
479 case Instruction::AGET_OBJECT:
480 case Instruction::AGET_BOOLEAN:
481 case Instruction::AGET_BYTE:
482 case Instruction::AGET_CHAR:
483 case Instruction::AGET_SHORT:
484 ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL,
485 "Attempt to read from null array");
486 break;
487 case Instruction::APUT:
488 case Instruction::APUT_WIDE:
489 case Instruction::APUT_OBJECT:
490 case Instruction::APUT_BOOLEAN:
491 case Instruction::APUT_BYTE:
492 case Instruction::APUT_CHAR:
493 case Instruction::APUT_SHORT:
494 ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL,
495 "Attempt to write to null array");
496 break;
497 case Instruction::ARRAY_LENGTH:
498 ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL,
499 "Attempt to get length of null array");
500 break;
501 default: {
502 // TODO: We should have covered all the cases where we expect a NPE above, this
503 // message/logging is so we can improve any cases we've missed in the future.
504 const DexFile& dex_file =
505 *throw_location.GetMethod()->GetDeclaringClass()->GetDexCache()->GetDexFile();
506 ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL,
507 StringPrintf("Null pointer exception during instruction '%s'",
508 instr->DumpString(&dex_file).c_str()).c_str());
509 break;
510 }
511 }
512}
513
514void ThrowNullPointerException(const ThrowLocation* throw_location, const char* msg) {
515 ThrowException(throw_location, "Ljava/lang/NullPointerException;", NULL, msg);
516}
517
518// RuntimeException
519
520void ThrowRuntimeException(const char* fmt, ...) {
521 va_list args;
522 va_start(args, fmt);
523 ThrowException(NULL, "Ljava/lang/RuntimeException;", NULL, fmt, &args);
524 va_end(args);
525}
526
527// VerifyError
528
Ian Rogersef7d42f2014-01-06 12:55:46 -0800529void ThrowVerifyError(mirror::Class* referrer, const char* fmt, ...) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800530 va_list args;
531 va_start(args, fmt);
532 ThrowException(NULL, "Ljava/lang/VerifyError;", referrer, fmt, &args);
533 va_end(args);
Ian Rogers87e552d2012-08-31 15:54:48 -0700534}
535
536} // namespace art