Home | History | Annotate | Download | only in runtime
      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 <sstream>
     20 
     21 #include "ScopedLocalRef.h"
     22 
     23 #include "art_field-inl.h"
     24 #include "art_method-inl.h"
     25 #include "base/logging.h"
     26 #include "class_linker-inl.h"
     27 #include "dex_file-inl.h"
     28 #include "dex_instruction-inl.h"
     29 #include "invoke_type.h"
     30 #include "mirror/class-inl.h"
     31 #include "mirror/object-inl.h"
     32 #include "mirror/object_array-inl.h"
     33 #include "thread.h"
     34 #include "verifier/method_verifier.h"
     35 
     36 namespace art {
     37 
     38 static void AddReferrerLocation(std::ostream& os, mirror::Class* referrer)
     39     SHARED_REQUIRES(Locks::mutator_lock_) {
     40   if (referrer != nullptr) {
     41     std::string location(referrer->GetLocation());
     42     if (!location.empty()) {
     43       os << " (declaration of '" << PrettyDescriptor(referrer)
     44             << "' appears in " << location << ")";
     45     }
     46   }
     47 }
     48 
     49 static void ThrowException(const char* exception_descriptor,
     50                            mirror::Class* referrer, const char* fmt, va_list* args = nullptr)
     51     SHARED_REQUIRES(Locks::mutator_lock_) {
     52   std::ostringstream msg;
     53   if (args != nullptr) {
     54     std::string vmsg;
     55     StringAppendV(&vmsg, fmt, *args);
     56     msg << vmsg;
     57   } else {
     58     msg << fmt;
     59   }
     60   AddReferrerLocation(msg, referrer);
     61   Thread* self = Thread::Current();
     62   self->ThrowNewException(exception_descriptor, msg.str().c_str());
     63 }
     64 
     65 static void ThrowWrappedException(const char* exception_descriptor,
     66                                   mirror::Class* referrer, const char* fmt, va_list* args = nullptr)
     67     SHARED_REQUIRES(Locks::mutator_lock_) {
     68   std::ostringstream msg;
     69   if (args != nullptr) {
     70     std::string vmsg;
     71     StringAppendV(&vmsg, fmt, *args);
     72     msg << vmsg;
     73   } else {
     74     msg << fmt;
     75   }
     76   AddReferrerLocation(msg, referrer);
     77   Thread* self = Thread::Current();
     78   self->ThrowNewWrappedException(exception_descriptor, msg.str().c_str());
     79 }
     80 
     81 // AbstractMethodError
     82 
     83 void ThrowAbstractMethodError(ArtMethod* method) {
     84   ThrowException("Ljava/lang/AbstractMethodError;", nullptr,
     85                  StringPrintf("abstract method \"%s\"",
     86                               PrettyMethod(method).c_str()).c_str());
     87 }
     88 
     89 void ThrowAbstractMethodError(uint32_t method_idx, const DexFile& dex_file) {
     90   ThrowException("Ljava/lang/AbstractMethodError;", /* referrer */ nullptr,
     91                  StringPrintf("abstract method \"%s\"",
     92                               PrettyMethod(method_idx,
     93                                            dex_file,
     94                                            /* with_signature */ true).c_str()).c_str());
     95 }
     96 
     97 // ArithmeticException
     98 
     99 void ThrowArithmeticExceptionDivideByZero() {
    100   ThrowException("Ljava/lang/ArithmeticException;", nullptr, "divide by zero");
    101 }
    102 
    103 // ArrayIndexOutOfBoundsException
    104 
    105 void ThrowArrayIndexOutOfBoundsException(int index, int length) {
    106   ThrowException("Ljava/lang/ArrayIndexOutOfBoundsException;", nullptr,
    107                  StringPrintf("length=%d; index=%d", length, index).c_str());
    108 }
    109 
    110 // ArrayStoreException
    111 
    112 void ThrowArrayStoreException(mirror::Class* element_class, mirror::Class* array_class) {
    113   ThrowException("Ljava/lang/ArrayStoreException;", nullptr,
    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 
    121 void ThrowClassCastException(mirror::Class* dest_type, mirror::Class* src_type) {
    122   ThrowException("Ljava/lang/ClassCastException;", nullptr,
    123                  StringPrintf("%s cannot be cast to %s",
    124                               PrettyDescriptor(src_type).c_str(),
    125                               PrettyDescriptor(dest_type).c_str()).c_str());
    126 }
    127 
    128 void ThrowClassCastException(const char* msg) {
    129   ThrowException("Ljava/lang/ClassCastException;", nullptr, msg);
    130 }
    131 
    132 // ClassCircularityError
    133 
    134 void ThrowClassCircularityError(mirror::Class* c) {
    135   std::ostringstream msg;
    136   msg << PrettyDescriptor(c);
    137   ThrowException("Ljava/lang/ClassCircularityError;", c, msg.str().c_str());
    138 }
    139 
    140 void ThrowClassCircularityError(mirror::Class* c, const char* fmt, ...) {
    141   va_list args;
    142   va_start(args, fmt);
    143   ThrowException("Ljava/lang/ClassCircularityError;", c, fmt, &args);
    144   va_end(args);
    145 }
    146 
    147 // ClassFormatError
    148 
    149 void ThrowClassFormatError(mirror::Class* referrer, const char* fmt, ...) {
    150   va_list args;
    151   va_start(args, fmt);
    152   ThrowException("Ljava/lang/ClassFormatError;", referrer, fmt, &args);
    153   va_end(args);}
    154 
    155 // IllegalAccessError
    156 
    157 void ThrowIllegalAccessErrorClass(mirror::Class* referrer, mirror::Class* accessed) {
    158   std::ostringstream msg;
    159   msg << "Illegal class access: '" << PrettyDescriptor(referrer) << "' attempting to access '"
    160       << PrettyDescriptor(accessed) << "'";
    161   ThrowException("Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
    162 }
    163 
    164 void ThrowIllegalAccessErrorClassForMethodDispatch(mirror::Class* referrer, mirror::Class* accessed,
    165                                                    ArtMethod* called,
    166                                                    InvokeType type) {
    167   std::ostringstream msg;
    168   msg << "Illegal class access ('" << PrettyDescriptor(referrer) << "' attempting to access '"
    169       << PrettyDescriptor(accessed) << "') in attempt to invoke " << type
    170       << " method " << PrettyMethod(called).c_str();
    171   ThrowException("Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
    172 }
    173 
    174 void ThrowIllegalAccessErrorMethod(mirror::Class* referrer, ArtMethod* accessed) {
    175   std::ostringstream msg;
    176   msg << "Method '" << PrettyMethod(accessed) << "' is inaccessible to class '"
    177       << PrettyDescriptor(referrer) << "'";
    178   ThrowException("Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
    179 }
    180 
    181 void ThrowIllegalAccessErrorField(mirror::Class* referrer, ArtField* accessed) {
    182   std::ostringstream msg;
    183   msg << "Field '" << PrettyField(accessed, false) << "' is inaccessible to class '"
    184       << PrettyDescriptor(referrer) << "'";
    185   ThrowException("Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
    186 }
    187 
    188 void ThrowIllegalAccessErrorFinalField(ArtMethod* referrer, ArtField* accessed) {
    189   std::ostringstream msg;
    190   msg << "Final field '" << PrettyField(accessed, false) << "' cannot be written to by method '"
    191       << PrettyMethod(referrer) << "'";
    192   ThrowException("Ljava/lang/IllegalAccessError;",
    193                  referrer != nullptr ? referrer->GetDeclaringClass() : nullptr,
    194                  msg.str().c_str());
    195 }
    196 
    197 void ThrowIllegalAccessError(mirror::Class* referrer, const char* fmt, ...) {
    198   va_list args;
    199   va_start(args, fmt);
    200   ThrowException("Ljava/lang/IllegalAccessError;", referrer, fmt, &args);
    201   va_end(args);
    202 }
    203 
    204 // IllegalAccessException
    205 
    206 void ThrowIllegalAccessException(const char* msg) {
    207   ThrowException("Ljava/lang/IllegalAccessException;", nullptr, msg);
    208 }
    209 
    210 // IllegalArgumentException
    211 
    212 void ThrowIllegalArgumentException(const char* msg) {
    213   ThrowException("Ljava/lang/IllegalArgumentException;", nullptr, msg);
    214 }
    215 
    216 
    217 // IncompatibleClassChangeError
    218 
    219 void ThrowIncompatibleClassChangeError(InvokeType expected_type, InvokeType found_type,
    220                                        ArtMethod* method, ArtMethod* referrer) {
    221   std::ostringstream msg;
    222   msg << "The method '" << PrettyMethod(method) << "' was expected to be of type "
    223       << expected_type << " but instead was found to be of type " << found_type;
    224   ThrowException("Ljava/lang/IncompatibleClassChangeError;",
    225                  referrer != nullptr ? referrer->GetDeclaringClass() : nullptr,
    226                  msg.str().c_str());
    227 }
    228 
    229 void ThrowIncompatibleClassChangeErrorClassForInterfaceSuper(ArtMethod* method,
    230                                                              mirror::Class* target_class,
    231                                                              mirror::Object* this_object,
    232                                                              ArtMethod* referrer) {
    233   // Referrer is calling interface_method on this_object, however, the interface_method isn't
    234   // implemented by this_object.
    235   CHECK(this_object != nullptr);
    236   std::ostringstream msg;
    237   msg << "Class '" << PrettyDescriptor(this_object->GetClass())
    238       << "' does not implement interface '" << PrettyDescriptor(target_class) << "' in call to '"
    239       << PrettyMethod(method) << "'";
    240   ThrowException("Ljava/lang/IncompatibleClassChangeError;",
    241                  referrer != nullptr ? referrer->GetDeclaringClass() : nullptr,
    242                  msg.str().c_str());
    243 }
    244 
    245 void ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(ArtMethod* interface_method,
    246                                                                 mirror::Object* this_object,
    247                                                                 ArtMethod* referrer) {
    248   // Referrer is calling interface_method on this_object, however, the interface_method isn't
    249   // implemented by this_object.
    250   CHECK(this_object != nullptr);
    251   std::ostringstream msg;
    252   msg << "Class '" << PrettyDescriptor(this_object->GetClass())
    253       << "' does not implement interface '"
    254       << PrettyDescriptor(interface_method->GetDeclaringClass())
    255       << "' in call to '" << PrettyMethod(interface_method) << "'";
    256   ThrowException("Ljava/lang/IncompatibleClassChangeError;",
    257                  referrer != nullptr ? referrer->GetDeclaringClass() : nullptr,
    258                  msg.str().c_str());
    259 }
    260 
    261 void ThrowIncompatibleClassChangeErrorField(ArtField* resolved_field, bool is_static,
    262                                             ArtMethod* referrer) {
    263   std::ostringstream msg;
    264   msg << "Expected '" << PrettyField(resolved_field) << "' to be a "
    265       << (is_static ? "static" : "instance") << " field" << " rather than a "
    266       << (is_static ? "instance" : "static") << " field";
    267   ThrowException("Ljava/lang/IncompatibleClassChangeError;", referrer->GetDeclaringClass(),
    268                  msg.str().c_str());
    269 }
    270 
    271 void ThrowIncompatibleClassChangeError(mirror::Class* referrer, const char* fmt, ...) {
    272   va_list args;
    273   va_start(args, fmt);
    274   ThrowException("Ljava/lang/IncompatibleClassChangeError;", referrer, fmt, &args);
    275   va_end(args);
    276 }
    277 
    278 void ThrowIncompatibleClassChangeErrorForMethodConflict(ArtMethod* method) {
    279   DCHECK(method != nullptr);
    280   ThrowException("Ljava/lang/IncompatibleClassChangeError;",
    281                  /*referrer*/nullptr,
    282                  StringPrintf("Conflicting default method implementations %s",
    283                               PrettyMethod(method).c_str()).c_str());
    284 }
    285 
    286 
    287 // IOException
    288 
    289 void ThrowIOException(const char* fmt, ...) {
    290   va_list args;
    291   va_start(args, fmt);
    292   ThrowException("Ljava/io/IOException;", nullptr, fmt, &args);
    293   va_end(args);
    294 }
    295 
    296 void ThrowWrappedIOException(const char* fmt, ...) {
    297   va_list args;
    298   va_start(args, fmt);
    299   ThrowWrappedException("Ljava/io/IOException;", nullptr, fmt, &args);
    300   va_end(args);
    301 }
    302 
    303 // LinkageError
    304 
    305 void ThrowLinkageError(mirror::Class* referrer, const char* fmt, ...) {
    306   va_list args;
    307   va_start(args, fmt);
    308   ThrowException("Ljava/lang/LinkageError;", referrer, fmt, &args);
    309   va_end(args);
    310 }
    311 
    312 void ThrowWrappedLinkageError(mirror::Class* referrer, const char* fmt, ...) {
    313   va_list args;
    314   va_start(args, fmt);
    315   ThrowWrappedException("Ljava/lang/LinkageError;", referrer, fmt, &args);
    316   va_end(args);
    317 }
    318 
    319 // NegativeArraySizeException
    320 
    321 void ThrowNegativeArraySizeException(int size) {
    322   ThrowException("Ljava/lang/NegativeArraySizeException;", nullptr,
    323                  StringPrintf("%d", size).c_str());
    324 }
    325 
    326 void ThrowNegativeArraySizeException(const char* msg) {
    327   ThrowException("Ljava/lang/NegativeArraySizeException;", nullptr, msg);
    328 }
    329 
    330 // NoSuchFieldError
    331 
    332 void ThrowNoSuchFieldError(const StringPiece& scope, mirror::Class* c,
    333                            const StringPiece& type, const StringPiece& name) {
    334   std::ostringstream msg;
    335   std::string temp;
    336   msg << "No " << scope << "field " << name << " of type " << type
    337       << " in class " << c->GetDescriptor(&temp) << " or its superclasses";
    338   ThrowException("Ljava/lang/NoSuchFieldError;", c, msg.str().c_str());
    339 }
    340 
    341 void ThrowNoSuchFieldException(mirror::Class* c, const StringPiece& name) {
    342   std::ostringstream msg;
    343   std::string temp;
    344   msg << "No field " << name << " in class " << c->GetDescriptor(&temp);
    345   ThrowException("Ljava/lang/NoSuchFieldException;", c, msg.str().c_str());
    346 }
    347 
    348 // NoSuchMethodError
    349 
    350 void ThrowNoSuchMethodError(InvokeType type, mirror::Class* c, const StringPiece& name,
    351                             const Signature& signature) {
    352   std::ostringstream msg;
    353   std::string temp;
    354   msg << "No " << type << " method " << name << signature
    355       << " in class " << c->GetDescriptor(&temp) << " or its super classes";
    356   ThrowException("Ljava/lang/NoSuchMethodError;", c, msg.str().c_str());
    357 }
    358 
    359 void ThrowNoSuchMethodError(uint32_t method_idx) {
    360   ArtMethod* method = Thread::Current()->GetCurrentMethod(nullptr);
    361   mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
    362   const DexFile& dex_file = *dex_cache->GetDexFile();
    363   std::ostringstream msg;
    364   msg << "No method '" << PrettyMethod(method_idx, dex_file, true) << "'";
    365   ThrowException("Ljava/lang/NoSuchMethodError;",
    366                  method->GetDeclaringClass(), msg.str().c_str());
    367 }
    368 
    369 // NullPointerException
    370 
    371 void ThrowNullPointerExceptionForFieldAccess(ArtField* field, bool is_read) {
    372   std::ostringstream msg;
    373   msg << "Attempt to " << (is_read ? "read from" : "write to")
    374       << " field '" << PrettyField(field, true) << "' on a null object reference";
    375   ThrowException("Ljava/lang/NullPointerException;", nullptr, msg.str().c_str());
    376 }
    377 
    378 static void ThrowNullPointerExceptionForMethodAccessImpl(uint32_t method_idx,
    379                                                          const DexFile& dex_file,
    380                                                          InvokeType type)
    381     SHARED_REQUIRES(Locks::mutator_lock_) {
    382   std::ostringstream msg;
    383   msg << "Attempt to invoke " << type << " method '"
    384       << PrettyMethod(method_idx, dex_file, true) << "' on a null object reference";
    385   ThrowException("Ljava/lang/NullPointerException;", nullptr, msg.str().c_str());
    386 }
    387 
    388 void ThrowNullPointerExceptionForMethodAccess(uint32_t method_idx,
    389                                               InvokeType type) {
    390   mirror::DexCache* dex_cache =
    391       Thread::Current()->GetCurrentMethod(nullptr)->GetDeclaringClass()->GetDexCache();
    392   const DexFile& dex_file = *dex_cache->GetDexFile();
    393   ThrowNullPointerExceptionForMethodAccessImpl(method_idx, dex_file, type);
    394 }
    395 
    396 void ThrowNullPointerExceptionForMethodAccess(ArtMethod* method,
    397                                               InvokeType type) {
    398   mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
    399   const DexFile& dex_file = *dex_cache->GetDexFile();
    400   ThrowNullPointerExceptionForMethodAccessImpl(method->GetDexMethodIndex(),
    401                                                dex_file, type);
    402 }
    403 
    404 void ThrowNullPointerExceptionFromDexPC() {
    405   uint32_t throw_dex_pc;
    406   ArtMethod* method = Thread::Current()->GetCurrentMethod(&throw_dex_pc);
    407   const DexFile::CodeItem* code = method->GetCodeItem();
    408   CHECK_LT(throw_dex_pc, code->insns_size_in_code_units_);
    409   const Instruction* instr = Instruction::At(&code->insns_[throw_dex_pc]);
    410   switch (instr->Opcode()) {
    411     case Instruction::INVOKE_DIRECT:
    412       ThrowNullPointerExceptionForMethodAccess(instr->VRegB_35c(), kDirect);
    413       break;
    414     case Instruction::INVOKE_DIRECT_RANGE:
    415       ThrowNullPointerExceptionForMethodAccess(instr->VRegB_3rc(), kDirect);
    416       break;
    417     case Instruction::INVOKE_VIRTUAL:
    418       ThrowNullPointerExceptionForMethodAccess(instr->VRegB_35c(), kVirtual);
    419       break;
    420     case Instruction::INVOKE_VIRTUAL_RANGE:
    421       ThrowNullPointerExceptionForMethodAccess(instr->VRegB_3rc(), kVirtual);
    422       break;
    423     case Instruction::INVOKE_INTERFACE:
    424       ThrowNullPointerExceptionForMethodAccess(instr->VRegB_35c(), kInterface);
    425       break;
    426     case Instruction::INVOKE_INTERFACE_RANGE:
    427       ThrowNullPointerExceptionForMethodAccess(instr->VRegB_3rc(), kInterface);
    428       break;
    429     case Instruction::INVOKE_VIRTUAL_QUICK:
    430     case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
    431       // Since we replaced the method index, we ask the verifier to tell us which
    432       // method is invoked at this location.
    433       ArtMethod* invoked_method =
    434           verifier::MethodVerifier::FindInvokedMethodAtDexPc(method, throw_dex_pc);
    435       if (invoked_method != nullptr) {
    436         // NPE with precise message.
    437         ThrowNullPointerExceptionForMethodAccess(invoked_method, kVirtual);
    438       } else {
    439         // NPE with imprecise message.
    440         ThrowNullPointerException("Attempt to invoke a virtual method on a null object reference");
    441       }
    442       break;
    443     }
    444     case Instruction::IGET:
    445     case Instruction::IGET_WIDE:
    446     case Instruction::IGET_OBJECT:
    447     case Instruction::IGET_BOOLEAN:
    448     case Instruction::IGET_BYTE:
    449     case Instruction::IGET_CHAR:
    450     case Instruction::IGET_SHORT: {
    451       ArtField* field =
    452           Runtime::Current()->GetClassLinker()->ResolveField(instr->VRegC_22c(), method, false);
    453       ThrowNullPointerExceptionForFieldAccess(field, true /* read */);
    454       break;
    455     }
    456     case Instruction::IGET_QUICK:
    457     case Instruction::IGET_BOOLEAN_QUICK:
    458     case Instruction::IGET_BYTE_QUICK:
    459     case Instruction::IGET_CHAR_QUICK:
    460     case Instruction::IGET_SHORT_QUICK:
    461     case Instruction::IGET_WIDE_QUICK:
    462     case Instruction::IGET_OBJECT_QUICK: {
    463       // Since we replaced the field index, we ask the verifier to tell us which
    464       // field is accessed at this location.
    465       ArtField* field =
    466           verifier::MethodVerifier::FindAccessedFieldAtDexPc(method, throw_dex_pc);
    467       if (field != nullptr) {
    468         // NPE with precise message.
    469         ThrowNullPointerExceptionForFieldAccess(field, true /* read */);
    470       } else {
    471         // NPE with imprecise message.
    472         ThrowNullPointerException("Attempt to read from a field on a null object reference");
    473       }
    474       break;
    475     }
    476     case Instruction::IPUT:
    477     case Instruction::IPUT_WIDE:
    478     case Instruction::IPUT_OBJECT:
    479     case Instruction::IPUT_BOOLEAN:
    480     case Instruction::IPUT_BYTE:
    481     case Instruction::IPUT_CHAR:
    482     case Instruction::IPUT_SHORT: {
    483       ArtField* field =
    484           Runtime::Current()->GetClassLinker()->ResolveField(instr->VRegC_22c(), method, false);
    485       ThrowNullPointerExceptionForFieldAccess(field, false /* write */);
    486       break;
    487     }
    488     case Instruction::IPUT_QUICK:
    489     case Instruction::IPUT_BOOLEAN_QUICK:
    490     case Instruction::IPUT_BYTE_QUICK:
    491     case Instruction::IPUT_CHAR_QUICK:
    492     case Instruction::IPUT_SHORT_QUICK:
    493     case Instruction::IPUT_WIDE_QUICK:
    494     case Instruction::IPUT_OBJECT_QUICK: {
    495       // Since we replaced the field index, we ask the verifier to tell us which
    496       // field is accessed at this location.
    497       ArtField* field =
    498           verifier::MethodVerifier::FindAccessedFieldAtDexPc(method, throw_dex_pc);
    499       if (field != nullptr) {
    500         // NPE with precise message.
    501         ThrowNullPointerExceptionForFieldAccess(field, false /* write */);
    502       } else {
    503         // NPE with imprecise message.
    504         ThrowNullPointerException("Attempt to write to a field on a null object reference");
    505       }
    506       break;
    507     }
    508     case Instruction::AGET:
    509     case Instruction::AGET_WIDE:
    510     case Instruction::AGET_OBJECT:
    511     case Instruction::AGET_BOOLEAN:
    512     case Instruction::AGET_BYTE:
    513     case Instruction::AGET_CHAR:
    514     case Instruction::AGET_SHORT:
    515       ThrowException("Ljava/lang/NullPointerException;", nullptr,
    516                      "Attempt to read from null array");
    517       break;
    518     case Instruction::APUT:
    519     case Instruction::APUT_WIDE:
    520     case Instruction::APUT_OBJECT:
    521     case Instruction::APUT_BOOLEAN:
    522     case Instruction::APUT_BYTE:
    523     case Instruction::APUT_CHAR:
    524     case Instruction::APUT_SHORT:
    525       ThrowException("Ljava/lang/NullPointerException;", nullptr,
    526                      "Attempt to write to null array");
    527       break;
    528     case Instruction::ARRAY_LENGTH:
    529       ThrowException("Ljava/lang/NullPointerException;", nullptr,
    530                      "Attempt to get length of null array");
    531       break;
    532     default: {
    533       // TODO: We should have covered all the cases where we expect a NPE above, this
    534       //       message/logging is so we can improve any cases we've missed in the future.
    535       const DexFile* dex_file =
    536           method->GetDeclaringClass()->GetDexCache()->GetDexFile();
    537       ThrowException("Ljava/lang/NullPointerException;", nullptr,
    538                      StringPrintf("Null pointer exception during instruction '%s'",
    539                                   instr->DumpString(dex_file).c_str()).c_str());
    540       break;
    541     }
    542   }
    543 }
    544 
    545 void ThrowNullPointerException(const char* msg) {
    546   ThrowException("Ljava/lang/NullPointerException;", nullptr, msg);
    547 }
    548 
    549 // RuntimeException
    550 
    551 void ThrowRuntimeException(const char* fmt, ...) {
    552   va_list args;
    553   va_start(args, fmt);
    554   ThrowException("Ljava/lang/RuntimeException;", nullptr, fmt, &args);
    555   va_end(args);
    556 }
    557 
    558 // Stack overflow.
    559 
    560 void ThrowStackOverflowError(Thread* self) {
    561   if (self->IsHandlingStackOverflow()) {
    562     LOG(ERROR) << "Recursive stack overflow.";
    563     // We don't fail here because SetStackEndForStackOverflow will print better diagnostics.
    564   }
    565 
    566   self->SetStackEndForStackOverflow();  // Allow space on the stack for constructor to execute.
    567   JNIEnvExt* env = self->GetJniEnv();
    568   std::string msg("stack size ");
    569   msg += PrettySize(self->GetStackSize());
    570 
    571   // Avoid running Java code for exception initialization.
    572   // TODO: Checks to make this a bit less brittle.
    573 
    574   std::string error_msg;
    575 
    576   // Allocate an uninitialized object.
    577   ScopedLocalRef<jobject> exc(env,
    578                               env->AllocObject(WellKnownClasses::java_lang_StackOverflowError));
    579   if (exc.get() != nullptr) {
    580     // "Initialize".
    581     // StackOverflowError -> VirtualMachineError -> Error -> Throwable -> Object.
    582     // Only Throwable has "custom" fields:
    583     //   String detailMessage.
    584     //   Throwable cause (= this).
    585     //   List<Throwable> suppressedExceptions (= Collections.emptyList()).
    586     //   Object stackState;
    587     //   StackTraceElement[] stackTrace;
    588     // Only Throwable has a non-empty constructor:
    589     //   this.stackTrace = EmptyArray.STACK_TRACE_ELEMENT;
    590     //   fillInStackTrace();
    591 
    592     // detailMessage.
    593     // TODO: Use String::FromModifiedUTF...?
    594     ScopedLocalRef<jstring> s(env, env->NewStringUTF(msg.c_str()));
    595     if (s.get() != nullptr) {
    596       env->SetObjectField(exc.get(), WellKnownClasses::java_lang_Throwable_detailMessage, s.get());
    597 
    598       // cause.
    599       env->SetObjectField(exc.get(), WellKnownClasses::java_lang_Throwable_cause, exc.get());
    600 
    601       // suppressedExceptions.
    602       ScopedLocalRef<jobject> emptylist(env, env->GetStaticObjectField(
    603           WellKnownClasses::java_util_Collections,
    604           WellKnownClasses::java_util_Collections_EMPTY_LIST));
    605       CHECK(emptylist.get() != nullptr);
    606       env->SetObjectField(exc.get(),
    607                           WellKnownClasses::java_lang_Throwable_suppressedExceptions,
    608                           emptylist.get());
    609 
    610       // stackState is set as result of fillInStackTrace. fillInStackTrace calls
    611       // nativeFillInStackTrace.
    612       ScopedLocalRef<jobject> stack_state_val(env, nullptr);
    613       {
    614         ScopedObjectAccessUnchecked soa(env);
    615         stack_state_val.reset(soa.Self()->CreateInternalStackTrace<false>(soa));
    616       }
    617       if (stack_state_val.get() != nullptr) {
    618         env->SetObjectField(exc.get(),
    619                             WellKnownClasses::java_lang_Throwable_stackState,
    620                             stack_state_val.get());
    621 
    622         // stackTrace.
    623         ScopedLocalRef<jobject> stack_trace_elem(env, env->GetStaticObjectField(
    624             WellKnownClasses::libcore_util_EmptyArray,
    625             WellKnownClasses::libcore_util_EmptyArray_STACK_TRACE_ELEMENT));
    626         env->SetObjectField(exc.get(),
    627                             WellKnownClasses::java_lang_Throwable_stackTrace,
    628                             stack_trace_elem.get());
    629       } else {
    630         error_msg = "Could not create stack trace.";
    631       }
    632       // Throw the exception.
    633       self->SetException(reinterpret_cast<mirror::Throwable*>(self->DecodeJObject(exc.get())));
    634     } else {
    635       // Could not allocate a string object.
    636       error_msg = "Couldn't throw new StackOverflowError because JNI NewStringUTF failed.";
    637     }
    638   } else {
    639     error_msg = "Could not allocate StackOverflowError object.";
    640   }
    641 
    642   if (!error_msg.empty()) {
    643     LOG(WARNING) << error_msg;
    644     CHECK(self->IsExceptionPending());
    645   }
    646 
    647   bool explicit_overflow_check = Runtime::Current()->ExplicitStackOverflowChecks();
    648   self->ResetDefaultStackEnd();  // Return to default stack size.
    649 
    650   // And restore protection if implicit checks are on.
    651   if (!explicit_overflow_check) {
    652     self->ProtectStack();
    653   }
    654 }
    655 
    656 // VerifyError
    657 
    658 void ThrowVerifyError(mirror::Class* referrer, const char* fmt, ...) {
    659   va_list args;
    660   va_start(args, fmt);
    661   ThrowException("Ljava/lang/VerifyError;", referrer, fmt, &args);
    662   va_end(args);
    663 }
    664 
    665 }  // namespace art
    666