• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
19 #include "base/logging.h"
20 #include "class_linker-inl.h"
21 #include "dex_file-inl.h"
22 #include "dex_instruction-inl.h"
23 #include "invoke_type.h"
24 #include "mirror/art_method-inl.h"
25 #include "mirror/class-inl.h"
26 #include "mirror/object-inl.h"
27 #include "mirror/object_array-inl.h"
28 #include "object_utils.h"
29 #include "thread.h"
30 #include "verifier/method_verifier.h"
31 
32 #include <sstream>
33 
34 namespace art {
35 
AddReferrerLocation(std::ostream & os,const mirror::Class * referrer)36 static void AddReferrerLocation(std::ostream& os, const mirror::Class* referrer)
37     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
38   if (referrer != NULL) {
39     ClassHelper kh(referrer);
40     std::string location(kh.GetLocation());
41     if (!location.empty()) {
42       os << " (declaration of '" << PrettyDescriptor(referrer)
43             << "' appears in " << location << ")";
44     }
45   }
46 }
47 
ThrowException(const ThrowLocation * throw_location,const char * exception_descriptor,const mirror::Class * referrer,const char * fmt,va_list * args=NULL)48 static void ThrowException(const ThrowLocation* throw_location, const char* exception_descriptor,
49                            const mirror::Class* referrer, const char* fmt, va_list* args = NULL)
50     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
51   std::ostringstream msg;
52   if (args != NULL) {
53     std::string vmsg;
54     StringAppendV(&vmsg, fmt, *args);
55     msg << vmsg;
56   } else {
57     msg << fmt;
58   }
59   AddReferrerLocation(msg, referrer);
60   Thread* self = Thread::Current();
61   if (throw_location == NULL) {
62     ThrowLocation computed_throw_location = self->GetCurrentLocationForThrow();
63     self->ThrowNewException(computed_throw_location, exception_descriptor, msg.str().c_str());
64   } else {
65     self->ThrowNewException(*throw_location, exception_descriptor, msg.str().c_str());
66   }
67 }
68 
69 // AbstractMethodError
70 
ThrowAbstractMethodError(const mirror::ArtMethod * method)71 void ThrowAbstractMethodError(const mirror::ArtMethod* method) {
72   ThrowException(NULL, "Ljava/lang/AbstractMethodError;", NULL,
73                  StringPrintf("abstract method \"%s\"",
74                               PrettyMethod(method).c_str()).c_str());
75 }
76 
77 // ArithmeticException
78 
ThrowArithmeticExceptionDivideByZero()79 void ThrowArithmeticExceptionDivideByZero() {
80   ThrowException(NULL, "Ljava/lang/ArithmeticException;", NULL, "divide by zero");
81 }
82 
83 // ArrayIndexOutOfBoundsException
84 
ThrowArrayIndexOutOfBoundsException(int index,int length)85 void ThrowArrayIndexOutOfBoundsException(int index, int length) {
86   ThrowException(NULL, "Ljava/lang/ArrayIndexOutOfBoundsException;", NULL,
87                  StringPrintf("length=%d; index=%d", length, index).c_str());
88 }
89 
90 // ArrayStoreException
91 
ThrowArrayStoreException(const mirror::Class * element_class,const mirror::Class * array_class)92 void ThrowArrayStoreException(const mirror::Class* element_class,
93                               const mirror::Class* array_class) {
94   ThrowException(NULL, "Ljava/lang/ArrayStoreException;", NULL,
95                  StringPrintf("%s cannot be stored in an array of type %s",
96                               PrettyDescriptor(element_class).c_str(),
97                               PrettyDescriptor(array_class).c_str()).c_str());
98 }
99 
100 // ClassCastException
101 
ThrowClassCastException(const mirror::Class * dest_type,const mirror::Class * src_type)102 void ThrowClassCastException(const mirror::Class* dest_type, const mirror::Class* src_type) {
103   ThrowException(NULL, "Ljava/lang/ClassCastException;", NULL,
104                  StringPrintf("%s cannot be cast to %s",
105                               PrettyDescriptor(src_type).c_str(),
106                               PrettyDescriptor(dest_type).c_str()).c_str());
107 }
108 
ThrowClassCastException(const ThrowLocation * throw_location,const char * msg)109 void ThrowClassCastException(const ThrowLocation* throw_location, const char* msg) {
110   ThrowException(throw_location, "Ljava/lang/ClassCastException;", NULL, msg);
111 }
112 
113 // ClassCircularityError
114 
ThrowClassCircularityError(mirror::Class * c)115 void ThrowClassCircularityError(mirror::Class* c) {
116   std::ostringstream msg;
117   msg << PrettyDescriptor(c);
118   ThrowException(NULL, "Ljava/lang/ClassCircularityError;", c, msg.str().c_str());
119 }
120 
121 // ClassFormatError
122 
ThrowClassFormatError(const mirror::Class * referrer,const char * fmt,...)123 void ThrowClassFormatError(const mirror::Class* referrer, const char* fmt, ...) {
124   va_list args;
125   va_start(args, fmt);
126   ThrowException(NULL, "Ljava/lang/ClassFormatError;", referrer, fmt, &args);
127   va_end(args);}
128 
129 // IllegalAccessError
130 
ThrowIllegalAccessErrorClass(mirror::Class * referrer,mirror::Class * accessed)131 void ThrowIllegalAccessErrorClass(mirror::Class* referrer, mirror::Class* accessed) {
132   std::ostringstream msg;
133   msg << "Illegal class access: '" << PrettyDescriptor(referrer) << "' attempting to access '"
134       << PrettyDescriptor(accessed) << "'";
135   ThrowException(NULL, "Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
136 }
137 
ThrowIllegalAccessErrorClassForMethodDispatch(mirror::Class * referrer,mirror::Class * accessed,const mirror::ArtMethod * caller,const mirror::ArtMethod * called,InvokeType type)138 void ThrowIllegalAccessErrorClassForMethodDispatch(mirror::Class* referrer, mirror::Class* accessed,
139                                                    const mirror::ArtMethod* caller,
140                                                    const mirror::ArtMethod* called,
141                                                    InvokeType type) {
142   std::ostringstream msg;
143   msg << "Illegal class access ('" << PrettyDescriptor(referrer) << "' attempting to access '"
144       << PrettyDescriptor(accessed) << "') in attempt to invoke " << type
145       << " method " << PrettyMethod(called).c_str();
146   ThrowException(NULL, "Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
147 }
148 
ThrowIllegalAccessErrorMethod(mirror::Class * referrer,mirror::ArtMethod * accessed)149 void ThrowIllegalAccessErrorMethod(mirror::Class* referrer, mirror::ArtMethod* accessed) {
150   std::ostringstream msg;
151   msg << "Method '" << PrettyMethod(accessed) << "' is inaccessible to class '"
152       << PrettyDescriptor(referrer) << "'";
153   ThrowException(NULL, "Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
154 }
155 
ThrowIllegalAccessErrorField(mirror::Class * referrer,mirror::ArtField * accessed)156 void ThrowIllegalAccessErrorField(mirror::Class* referrer, mirror::ArtField* accessed) {
157   std::ostringstream msg;
158   msg << "Field '" << PrettyField(accessed, false) << "' is inaccessible to class '"
159       << PrettyDescriptor(referrer) << "'";
160   ThrowException(NULL, "Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
161 }
162 
ThrowIllegalAccessErrorFinalField(const mirror::ArtMethod * referrer,mirror::ArtField * accessed)163 void ThrowIllegalAccessErrorFinalField(const mirror::ArtMethod* referrer,
164                                        mirror::ArtField* accessed) {
165   std::ostringstream msg;
166   msg << "Final field '" << PrettyField(accessed, false) << "' cannot be written to by method '"
167       << PrettyMethod(referrer) << "'";
168   ThrowException(NULL, "Ljava/lang/IllegalAccessError;",
169                  referrer != NULL ? referrer->GetClass() : NULL,
170                  msg.str().c_str());
171 }
172 
ThrowIllegalAccessError(mirror::Class * referrer,const char * fmt,...)173 void ThrowIllegalAccessError(mirror::Class* referrer, const char* fmt, ...) {
174   va_list args;
175   va_start(args, fmt);
176   ThrowException(NULL, "Ljava/lang/IllegalAccessError;", referrer, fmt, &args);
177   va_end(args);
178 }
179 
180 // IllegalArgumentException
181 
ThrowIllegalArgumentException(const ThrowLocation * throw_location,const char * msg)182 void ThrowIllegalArgumentException(const ThrowLocation* throw_location, const char* msg) {
183   ThrowException(throw_location, "Ljava/lang/IllegalArgumentException;", NULL, msg);
184 }
185 
186 
187 // IncompatibleClassChangeError
188 
ThrowIncompatibleClassChangeError(InvokeType expected_type,InvokeType found_type,mirror::ArtMethod * method,const mirror::ArtMethod * referrer)189 void ThrowIncompatibleClassChangeError(InvokeType expected_type, InvokeType found_type,
190                                        mirror::ArtMethod* method,
191                                        const mirror::ArtMethod* referrer) {
192   std::ostringstream msg;
193   msg << "The method '" << PrettyMethod(method) << "' was expected to be of type "
194       << expected_type << " but instead was found to be of type " << found_type;
195   ThrowException(NULL, "Ljava/lang/IncompatibleClassChangeError;",
196                  referrer != NULL ? referrer->GetClass() : NULL,
197                  msg.str().c_str());
198 }
199 
ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(const mirror::ArtMethod * interface_method,mirror::Object * this_object,const mirror::ArtMethod * referrer)200 void ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(const mirror::ArtMethod* interface_method,
201                                                                 mirror::Object* this_object,
202                                                                 const mirror::ArtMethod* referrer) {
203   // Referrer is calling interface_method on this_object, however, the interface_method isn't
204   // implemented by this_object.
205   CHECK(this_object != NULL);
206   std::ostringstream msg;
207   msg << "Class '" << PrettyDescriptor(this_object->GetClass())
208       << "' does not implement interface '"
209       << PrettyDescriptor(interface_method->GetDeclaringClass())
210       << "' in call to '" << PrettyMethod(interface_method) << "'";
211   ThrowException(NULL, "Ljava/lang/IncompatibleClassChangeError;",
212                  referrer != NULL ? referrer->GetClass() : NULL,
213                  msg.str().c_str());
214 }
215 
ThrowIncompatibleClassChangeErrorField(const mirror::ArtField * resolved_field,bool is_static,const mirror::ArtMethod * referrer)216 void ThrowIncompatibleClassChangeErrorField(const mirror::ArtField* resolved_field, bool is_static,
217                                             const mirror::ArtMethod* referrer) {
218   std::ostringstream msg;
219   msg << "Expected '" << PrettyField(resolved_field) << "' to be a "
220       << (is_static ? "static" : "instance") << " field" << " rather than a "
221       << (is_static ? "instance" : "static") << " field";
222   ThrowException(NULL, "Ljava/lang/IncompatibleClassChangeError;", referrer->GetClass(),
223                  msg.str().c_str());
224 }
225 
ThrowIncompatibleClassChangeError(const mirror::Class * referrer,const char * fmt,...)226 void ThrowIncompatibleClassChangeError(const mirror::Class* referrer, const char* fmt, ...) {
227   va_list args;
228   va_start(args, fmt);
229   ThrowException(NULL, "Ljava/lang/IncompatibleClassChangeError;", referrer, fmt, &args);
230   va_end(args);
231 }
232 
233 // LinkageError
234 
ThrowLinkageError(const mirror::Class * referrer,const char * fmt,...)235 void ThrowLinkageError(const mirror::Class* referrer, const char* fmt, ...) {
236   va_list args;
237   va_start(args, fmt);
238   ThrowException(NULL, "Ljava/lang/LinkageError;", referrer, fmt, &args);
239   va_end(args);
240 }
241 
242 // NegativeArraySizeException
243 
ThrowNegativeArraySizeException(int size)244 void ThrowNegativeArraySizeException(int size) {
245   ThrowException(NULL, "Ljava/lang/NegativeArraySizeException;", NULL,
246                  StringPrintf("%d", size).c_str());
247 }
248 
ThrowNegativeArraySizeException(const char * msg)249 void ThrowNegativeArraySizeException(const char* msg) {
250   ThrowException(NULL, "Ljava/lang/NegativeArraySizeException;", NULL, msg);
251 }
252 
253 // NoSuchFieldError
254 
ThrowNoSuchFieldError(const StringPiece & scope,mirror::Class * c,const StringPiece & type,const StringPiece & name)255 void ThrowNoSuchFieldError(const StringPiece& scope, mirror::Class* c,
256                            const StringPiece& type, const StringPiece& name)
257     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
258   ClassHelper kh(c);
259   std::ostringstream msg;
260   msg << "No " << scope << "field " << name << " of type " << type
261       << " in class " << kh.GetDescriptor() << " or its superclasses";
262   ThrowException(NULL, "Ljava/lang/NoSuchFieldError;", c, msg.str().c_str());
263 }
264 
265 // NoSuchMethodError
266 
ThrowNoSuchMethodError(InvokeType type,mirror::Class * c,const StringPiece & name,const StringPiece & signature)267 void ThrowNoSuchMethodError(InvokeType type, mirror::Class* c, const StringPiece& name,
268                             const StringPiece& signature) {
269   std::ostringstream msg;
270   ClassHelper kh(c);
271   msg << "No " << type << " method " << name << signature
272       << " in class " << kh.GetDescriptor() << " or its super classes";
273   ThrowException(NULL, "Ljava/lang/NoSuchMethodError;", c, msg.str().c_str());
274 }
275 
ThrowNoSuchMethodError(uint32_t method_idx)276 void ThrowNoSuchMethodError(uint32_t method_idx) {
277   Thread* self = Thread::Current();
278   ThrowLocation throw_location = self->GetCurrentLocationForThrow();
279   mirror::DexCache* dex_cache = throw_location.GetMethod()->GetDeclaringClass()->GetDexCache();
280   const DexFile& dex_file = *dex_cache->GetDexFile();
281   std::ostringstream msg;
282   msg << "No method '" << PrettyMethod(method_idx, dex_file, true) << "'";
283   ThrowException(&throw_location, "Ljava/lang/NoSuchMethodError;",
284                  throw_location.GetMethod()->GetDeclaringClass(), msg.str().c_str());
285 }
286 
287 // NullPointerException
288 
ThrowNullPointerExceptionForFieldAccess(const ThrowLocation & throw_location,mirror::ArtField * field,bool is_read)289 void ThrowNullPointerExceptionForFieldAccess(const ThrowLocation& throw_location,
290                                              mirror::ArtField* field, bool is_read) {
291   std::ostringstream msg;
292   msg << "Attempt to " << (is_read ? "read from" : "write to")
293       << " field '" << PrettyField(field, true) << "' on a null object reference";
294   ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL, msg.str().c_str());
295 }
296 
ThrowNullPointerExceptionForMethodAccessImpl(const ThrowLocation & throw_location,uint32_t method_idx,const DexFile & dex_file,InvokeType type)297 static void ThrowNullPointerExceptionForMethodAccessImpl(const ThrowLocation& throw_location,
298                                                          uint32_t method_idx,
299                                                          const DexFile& dex_file,
300                                                          InvokeType type)
301     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
302   std::ostringstream msg;
303   msg << "Attempt to invoke " << type << " method '"
304       << PrettyMethod(method_idx, dex_file, true) << "' on a null object reference";
305   ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL, msg.str().c_str());
306 }
307 
ThrowNullPointerExceptionForMethodAccess(const ThrowLocation & throw_location,uint32_t method_idx,InvokeType type)308 void ThrowNullPointerExceptionForMethodAccess(const ThrowLocation& throw_location,
309                                               uint32_t method_idx,
310                                               InvokeType type) {
311   mirror::DexCache* dex_cache = throw_location.GetMethod()->GetDeclaringClass()->GetDexCache();
312   const DexFile& dex_file = *dex_cache->GetDexFile();
313   ThrowNullPointerExceptionForMethodAccessImpl(throw_location, method_idx,
314                                                dex_file, type);
315 }
316 
ThrowNullPointerExceptionForMethodAccess(const ThrowLocation & throw_location,mirror::ArtMethod * method,InvokeType type)317 void ThrowNullPointerExceptionForMethodAccess(const ThrowLocation& throw_location,
318                                               mirror::ArtMethod* method,
319                                               InvokeType type) {
320   mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
321   const DexFile& dex_file = *dex_cache->GetDexFile();
322   ThrowNullPointerExceptionForMethodAccessImpl(throw_location, method->GetDexMethodIndex(),
323                                                dex_file, type);
324 }
325 
ThrowNullPointerExceptionFromDexPC(const ThrowLocation & throw_location)326 void ThrowNullPointerExceptionFromDexPC(const ThrowLocation& throw_location) {
327   const DexFile::CodeItem* code = MethodHelper(throw_location.GetMethod()).GetCodeItem();
328   uint32_t throw_dex_pc = throw_location.GetDexPc();
329   CHECK_LT(throw_dex_pc, code->insns_size_in_code_units_);
330   const Instruction* instr = Instruction::At(&code->insns_[throw_dex_pc]);
331   switch (instr->Opcode()) {
332     case Instruction::INVOKE_DIRECT:
333       ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_35c(), kDirect);
334       break;
335     case Instruction::INVOKE_DIRECT_RANGE:
336       ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_3rc(), kDirect);
337       break;
338     case Instruction::INVOKE_VIRTUAL:
339       ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_35c(), kVirtual);
340       break;
341     case Instruction::INVOKE_VIRTUAL_RANGE:
342       ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_3rc(), kVirtual);
343       break;
344     case Instruction::INVOKE_INTERFACE:
345       ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_35c(), kInterface);
346       break;
347     case Instruction::INVOKE_INTERFACE_RANGE:
348       ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_3rc(), kInterface);
349       break;
350     case Instruction::INVOKE_VIRTUAL_QUICK:
351     case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
352       // Since we replaced the method index, we ask the verifier to tell us which
353       // method is invoked at this location.
354       mirror::ArtMethod* method =
355           verifier::MethodVerifier::FindInvokedMethodAtDexPc(throw_location.GetMethod(),
356                                                              throw_location.GetDexPc());
357       if (method != NULL) {
358         // NPE with precise message.
359         ThrowNullPointerExceptionForMethodAccess(throw_location, method, kVirtual);
360       } else {
361         // NPE with imprecise message.
362         ThrowNullPointerException(&throw_location,
363                                   "Attempt to invoke a virtual method on a null object reference");
364       }
365       break;
366     }
367     case Instruction::IGET:
368     case Instruction::IGET_WIDE:
369     case Instruction::IGET_OBJECT:
370     case Instruction::IGET_BOOLEAN:
371     case Instruction::IGET_BYTE:
372     case Instruction::IGET_CHAR:
373     case Instruction::IGET_SHORT: {
374       mirror::ArtField* field =
375           Runtime::Current()->GetClassLinker()->ResolveField(instr->VRegC_22c(),
376                                                              throw_location.GetMethod(), false);
377       ThrowNullPointerExceptionForFieldAccess(throw_location, field, true /* read */);
378       break;
379     }
380     case Instruction::IGET_QUICK:
381     case Instruction::IGET_WIDE_QUICK:
382     case Instruction::IGET_OBJECT_QUICK: {
383       // Since we replaced the field index, we ask the verifier to tell us which
384       // field is accessed at this location.
385       mirror::ArtField* field =
386           verifier::MethodVerifier::FindAccessedFieldAtDexPc(throw_location.GetMethod(),
387                                                              throw_location.GetDexPc());
388       if (field != NULL) {
389         // NPE with precise message.
390         ThrowNullPointerExceptionForFieldAccess(throw_location, field, true /* read */);
391       } else {
392         // NPE with imprecise message.
393         ThrowNullPointerException(&throw_location,
394                                   "Attempt to read from a field on a null object reference");
395       }
396       break;
397     }
398     case Instruction::IPUT:
399     case Instruction::IPUT_WIDE:
400     case Instruction::IPUT_OBJECT:
401     case Instruction::IPUT_BOOLEAN:
402     case Instruction::IPUT_BYTE:
403     case Instruction::IPUT_CHAR:
404     case Instruction::IPUT_SHORT: {
405       mirror::ArtField* field =
406           Runtime::Current()->GetClassLinker()->ResolveField(instr->VRegC_22c(),
407                                                              throw_location.GetMethod(), false);
408       ThrowNullPointerExceptionForFieldAccess(throw_location, field, false /* write */);
409       break;
410     }
411     case Instruction::IPUT_QUICK:
412     case Instruction::IPUT_WIDE_QUICK:
413     case Instruction::IPUT_OBJECT_QUICK: {
414       // Since we replaced the field index, we ask the verifier to tell us which
415       // field is accessed at this location.
416       mirror::ArtField* field =
417           verifier::MethodVerifier::FindAccessedFieldAtDexPc(throw_location.GetMethod(),
418                                                              throw_location.GetDexPc());
419       if (field != NULL) {
420         // NPE with precise message.
421         ThrowNullPointerExceptionForFieldAccess(throw_location, field, false /* write */);
422       } else {
423         // NPE with imprecise message.
424         ThrowNullPointerException(&throw_location,
425                                   "Attempt to write to a field on a null object reference");
426       }
427       break;
428     }
429     case Instruction::AGET:
430     case Instruction::AGET_WIDE:
431     case Instruction::AGET_OBJECT:
432     case Instruction::AGET_BOOLEAN:
433     case Instruction::AGET_BYTE:
434     case Instruction::AGET_CHAR:
435     case Instruction::AGET_SHORT:
436       ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL,
437                      "Attempt to read from null array");
438       break;
439     case Instruction::APUT:
440     case Instruction::APUT_WIDE:
441     case Instruction::APUT_OBJECT:
442     case Instruction::APUT_BOOLEAN:
443     case Instruction::APUT_BYTE:
444     case Instruction::APUT_CHAR:
445     case Instruction::APUT_SHORT:
446       ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL,
447                      "Attempt to write to null array");
448       break;
449     case Instruction::ARRAY_LENGTH:
450       ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL,
451                      "Attempt to get length of null array");
452       break;
453     default: {
454       // TODO: We should have covered all the cases where we expect a NPE above, this
455       //       message/logging is so we can improve any cases we've missed in the future.
456       const DexFile& dex_file =
457           *throw_location.GetMethod()->GetDeclaringClass()->GetDexCache()->GetDexFile();
458       ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL,
459                      StringPrintf("Null pointer exception during instruction '%s'",
460                                   instr->DumpString(&dex_file).c_str()).c_str());
461       break;
462     }
463   }
464 }
465 
ThrowNullPointerException(const ThrowLocation * throw_location,const char * msg)466 void ThrowNullPointerException(const ThrowLocation* throw_location, const char* msg) {
467   ThrowException(throw_location, "Ljava/lang/NullPointerException;", NULL, msg);
468 }
469 
470 // RuntimeException
471 
ThrowRuntimeException(const char * fmt,...)472 void ThrowRuntimeException(const char* fmt, ...) {
473   va_list args;
474   va_start(args, fmt);
475   ThrowException(NULL, "Ljava/lang/RuntimeException;", NULL, fmt, &args);
476   va_end(args);
477 }
478 
479 // VerifyError
480 
ThrowVerifyError(const mirror::Class * referrer,const char * fmt,...)481 void ThrowVerifyError(const mirror::Class* referrer, const char* fmt, ...) {
482   va_list args;
483   va_start(args, fmt);
484   ThrowException(NULL, "Ljava/lang/VerifyError;", referrer, fmt, &args);
485   va_end(args);
486 }
487 
488 }  // namespace art
489