/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "common_throws.h"

#include "base/logging.h"
#include "class_linker-inl.h"
#include "dex_file-inl.h"
#include "dex_instruction-inl.h"
#include "invoke_type.h"
#include "mirror/abstract_method-inl.h"
#include "mirror/class-inl.h"
#include "mirror/object-inl.h"
#include "mirror/object_array-inl.h"
#include "object_utils.h"
#include "thread.h"
#include "verifier/method_verifier.h"

#include <sstream>

namespace art {

static void AddReferrerLocation(std::ostream& os, const mirror::Class* referrer)
    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  if (referrer != NULL) {
    ClassHelper kh(referrer);
    std::string location(kh.GetLocation());
    if (!location.empty()) {
      os << " (declaration of '" << PrettyDescriptor(referrer)
            << "' appears in " << location << ")";
    }
  }
}

static void ThrowException(const ThrowLocation* throw_location, const char* exception_descriptor,
                           const mirror::Class* referrer, const char* fmt, va_list* args = NULL)
    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  std::ostringstream msg;
  if (args != NULL) {
    std::string vmsg;
    StringAppendV(&vmsg, fmt, *args);
    msg << vmsg;
  } else {
    msg << fmt;
  }
  AddReferrerLocation(msg, referrer);
  Thread* self = Thread::Current();
  if (throw_location == NULL) {
    ThrowLocation computed_throw_location = self->GetCurrentLocationForThrow();
    self->ThrowNewException(computed_throw_location, exception_descriptor, msg.str().c_str());
  } else {
    self->ThrowNewException(*throw_location, exception_descriptor, msg.str().c_str());
  }
}

// AbstractMethodError

void ThrowAbstractMethodError(const mirror::AbstractMethod* method) {
  ThrowException(NULL, "Ljava/lang/AbstractMethodError;", NULL,
                 StringPrintf("abstract method \"%s\"",
                              PrettyMethod(method).c_str()).c_str());
}

// ArithmeticException

void ThrowArithmeticExceptionDivideByZero() {
  ThrowException(NULL, "Ljava/lang/ArithmeticException;", NULL, "divide by zero");
}

// ArrayIndexOutOfBoundsException

void ThrowArrayIndexOutOfBoundsException(int index, int length) {
  ThrowException(NULL, "Ljava/lang/ArrayIndexOutOfBoundsException;", NULL,
                 StringPrintf("length=%d; index=%d", length, index).c_str());
}

// ArrayStoreException

void ThrowArrayStoreException(const mirror::Class* element_class,
                              const mirror::Class* array_class) {
  ThrowException(NULL, "Ljava/lang/ArrayStoreException;", NULL,
                 StringPrintf("%s cannot be stored in an array of type %s",
                              PrettyDescriptor(element_class).c_str(),
                              PrettyDescriptor(array_class).c_str()).c_str());
}

// ClassCastException

void ThrowClassCastException(const mirror::Class* dest_type, const mirror::Class* src_type) {
  ThrowException(NULL, "Ljava/lang/ClassCastException;", NULL,
                 StringPrintf("%s cannot be cast to %s",
                              PrettyDescriptor(src_type).c_str(),
                              PrettyDescriptor(dest_type).c_str()).c_str());
}

void ThrowClassCastException(const ThrowLocation* throw_location, const char* msg) {
  ThrowException(throw_location, "Ljava/lang/ClassCastException;", NULL, msg);
}

// ClassCircularityError

void ThrowClassCircularityError(mirror::Class* c) {
  std::ostringstream msg;
  msg << PrettyDescriptor(c);
  ThrowException(NULL, "Ljava/lang/ClassCircularityError;", c, msg.str().c_str());
}

// ClassFormatError

void ThrowClassFormatError(const mirror::Class* referrer, const char* fmt, ...) {
  va_list args;
  va_start(args, fmt);
  ThrowException(NULL, "Ljava/lang/ClassFormatError;", referrer, fmt, &args);
  va_end(args);}

// IllegalAccessError

void ThrowIllegalAccessErrorClass(mirror::Class* referrer, mirror::Class* accessed) {
  std::ostringstream msg;
  msg << "Illegal class access: '" << PrettyDescriptor(referrer) << "' attempting to access '"
      << PrettyDescriptor(accessed) << "'";
  ThrowException(NULL, "Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
}

void ThrowIllegalAccessErrorClassForMethodDispatch(mirror::Class* referrer, mirror::Class* accessed,
                                                   const mirror::AbstractMethod* caller,
                                                   const mirror::AbstractMethod* called,
                                                   InvokeType type) {
  std::ostringstream msg;
  msg << "Illegal class access ('" << PrettyDescriptor(referrer) << "' attempting to access '"
      << PrettyDescriptor(accessed) << "') in attempt to invoke " << type
      << " method " << PrettyMethod(called).c_str();
  ThrowException(NULL, "Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
}

void ThrowIllegalAccessErrorMethod(mirror::Class* referrer, mirror::AbstractMethod* accessed) {
  std::ostringstream msg;
  msg << "Method '" << PrettyMethod(accessed) << "' is inaccessible to class '"
      << PrettyDescriptor(referrer) << "'";
  ThrowException(NULL, "Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
}

void ThrowIllegalAccessErrorField(mirror::Class* referrer, mirror::Field* accessed) {
  std::ostringstream msg;
  msg << "Field '" << PrettyField(accessed, false) << "' is inaccessible to class '"
      << PrettyDescriptor(referrer) << "'";
  ThrowException(NULL, "Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
}

void ThrowIllegalAccessErrorFinalField(const mirror::AbstractMethod* referrer,
                                       mirror::Field* accessed) {
  std::ostringstream msg;
  msg << "Final field '" << PrettyField(accessed, false) << "' cannot be written to by method '"
      << PrettyMethod(referrer) << "'";
  ThrowException(NULL, "Ljava/lang/IllegalAccessError;", referrer != NULL ? referrer->GetClass() : NULL,
                 msg.str().c_str());
}

void ThrowIllegalAccessError(mirror::Class* referrer, const char* fmt, ...){
  va_list args;
  va_start(args, fmt);
  ThrowException(NULL, "Ljava/lang/IllegalAccessError;", referrer, fmt, &args);
  va_end(args);
}

// IllegalArgumentException

void ThrowIllegalArgumentException(const ThrowLocation* throw_location, const char* msg) {
  ThrowException(throw_location, "Ljava/lang/IllegalArgumentException;", NULL, msg);
}


// IncompatibleClassChangeError

void ThrowIncompatibleClassChangeError(InvokeType expected_type, InvokeType found_type,
                                       mirror::AbstractMethod* method,
                                       const mirror::AbstractMethod* referrer) {
  std::ostringstream msg;
  msg << "The method '" << PrettyMethod(method) << "' was expected to be of type "
      << expected_type << " but instead was found to be of type " << found_type;
  ThrowException(NULL, "Ljava/lang/IncompatibleClassChangeError;",
                 referrer != NULL ? referrer->GetClass() : NULL,
                 msg.str().c_str());
}

void ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(const mirror::AbstractMethod* interface_method,
                                                                mirror::Object* this_object,
                                                                const mirror::AbstractMethod* referrer) {
  // Referrer is calling interface_method on this_object, however, the interface_method isn't
  // implemented by this_object.
  CHECK(this_object != NULL);
  std::ostringstream msg;
  msg << "Class '" << PrettyDescriptor(this_object->GetClass())
      << "' does not implement interface '"
      << PrettyDescriptor(interface_method->GetDeclaringClass())
      << "' in call to '" << PrettyMethod(interface_method) << "'";
  ThrowException(NULL, "Ljava/lang/IncompatibleClassChangeError;",
                 referrer != NULL ? referrer->GetClass() : NULL,
                 msg.str().c_str());
}

void ThrowIncompatibleClassChangeErrorField(const mirror::Field* resolved_field, bool is_static,
                                            const mirror::AbstractMethod* referrer) {
  std::ostringstream msg;
  msg << "Expected '" << PrettyField(resolved_field) << "' to be a "
      << (is_static ? "static" : "instance") << " field" << " rather than a "
      << (is_static ? "instance" : "static") << " field";
  ThrowException(NULL, "Ljava/lang/IncompatibleClassChangeError;", referrer->GetClass(),
                 msg.str().c_str());
}

void ThrowIncompatibleClassChangeError(const mirror::Class* referrer, const char* fmt, ...){
  va_list args;
  va_start(args, fmt);
  ThrowException(NULL, "Ljava/lang/IncompatibleClassChangeError;", referrer, fmt, &args);
  va_end(args);
}

// LinkageError

void ThrowLinkageError(const mirror::Class* referrer, const char* fmt, ...) {
  va_list args;
  va_start(args, fmt);
  ThrowException(NULL, "Ljava/lang/LinkageError;", referrer, fmt, &args);
  va_end(args);
}

// NegativeArraySizeException

void ThrowNegativeArraySizeException(int size) {
  ThrowException(NULL, "Ljava/lang/NegativeArraySizeException;", NULL, StringPrintf("%d", size).c_str());
}

void ThrowNegativeArraySizeException(const char* msg) {
  ThrowException(NULL, "Ljava/lang/NegativeArraySizeException;", NULL, msg);
}

// NoSuchFieldError

void ThrowNoSuchFieldError(const StringPiece& scope, mirror::Class* c,
                           const StringPiece& type, const StringPiece& name)
    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  ClassHelper kh(c);
  std::ostringstream msg;
  msg << "No " << scope << "field " << name << " of type " << type
      << " in class " << kh.GetDescriptor() << " or its superclasses";
  ThrowException(NULL, "Ljava/lang/NoSuchFieldError;", c, msg.str().c_str());
}

// NoSuchMethodError

void ThrowNoSuchMethodError(InvokeType type, mirror::Class* c, const StringPiece& name,
                            const StringPiece& signature) {
  std::ostringstream msg;
  ClassHelper kh(c);
  msg << "No " << type << " method " << name << signature
      << " in class " << kh.GetDescriptor() << " or its super classes";
  ThrowException(NULL, "Ljava/lang/NoSuchMethodError;", c, msg.str().c_str());
}

void ThrowNoSuchMethodError(uint32_t method_idx) {
  Thread* self = Thread::Current();
  ThrowLocation throw_location = self->GetCurrentLocationForThrow();
  mirror::DexCache* dex_cache = throw_location.GetMethod()->GetDeclaringClass()->GetDexCache();
  const DexFile& dex_file = *dex_cache->GetDexFile();
  std::ostringstream msg;
  msg << "No method '" << PrettyMethod(method_idx, dex_file, true) << "'";
  ThrowException(&throw_location, "Ljava/lang/NoSuchMethodError;",
                 throw_location.GetMethod()->GetDeclaringClass(), msg.str().c_str());
}

// NullPointerException

void ThrowNullPointerExceptionForFieldAccess(const ThrowLocation& throw_location,
                                             mirror::Field* field, bool is_read) {
  std::ostringstream msg;
  msg << "Attempt to " << (is_read ? "read from" : "write to")
      << " field '" << PrettyField(field, true) << "' on a null object reference";
  ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL, msg.str().c_str());
}

static void ThrowNullPointerExceptionForMethodAccessImpl(const ThrowLocation& throw_location,
                                                         uint32_t method_idx,
                                                         const DexFile& dex_file,
                                                         InvokeType type)
    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  std::ostringstream msg;
  msg << "Attempt to invoke " << type << " method '"
      << PrettyMethod(method_idx, dex_file, true) << "' on a null object reference";
  ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL, msg.str().c_str());
}

void ThrowNullPointerExceptionForMethodAccess(const ThrowLocation& throw_location, uint32_t method_idx,
                                              InvokeType type) {
  mirror::DexCache* dex_cache = throw_location.GetMethod()->GetDeclaringClass()->GetDexCache();
  const DexFile& dex_file = *dex_cache->GetDexFile();
  ThrowNullPointerExceptionForMethodAccessImpl(throw_location, method_idx,
                                               dex_file, type);
}

void ThrowNullPointerExceptionForMethodAccess(const ThrowLocation& throw_location,
                                              mirror::AbstractMethod* method,
                                              InvokeType type) {
  mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
  const DexFile& dex_file = *dex_cache->GetDexFile();
  ThrowNullPointerExceptionForMethodAccessImpl(throw_location, method->GetDexMethodIndex(),
                                               dex_file, type);
}

void ThrowNullPointerExceptionFromDexPC(const ThrowLocation& throw_location) {
  const DexFile::CodeItem* code = MethodHelper(throw_location.GetMethod()).GetCodeItem();
  uint32_t throw_dex_pc = throw_location.GetDexPc();
  CHECK_LT(throw_dex_pc, code->insns_size_in_code_units_);
  const Instruction* instr = Instruction::At(&code->insns_[throw_dex_pc]);
  switch (instr->Opcode()) {
    case Instruction::INVOKE_DIRECT:
      ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_35c(), kDirect);
      break;
    case Instruction::INVOKE_DIRECT_RANGE:
      ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_3rc(), kDirect);
      break;
    case Instruction::INVOKE_VIRTUAL:
      ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_35c(), kVirtual);
      break;
    case Instruction::INVOKE_VIRTUAL_RANGE:
      ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_3rc(), kVirtual);
      break;
    case Instruction::INVOKE_INTERFACE:
      ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_35c(), kInterface);
      break;
    case Instruction::INVOKE_INTERFACE_RANGE:
      ThrowNullPointerExceptionForMethodAccess(throw_location, instr->VRegB_3rc(), kInterface);
      break;
    case Instruction::INVOKE_VIRTUAL_QUICK:
    case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
      // Since we replaced the method index, we ask the verifier to tell us which
      // method is invoked at this location.
      mirror::AbstractMethod* method =
          verifier::MethodVerifier::FindInvokedMethodAtDexPc(throw_location.GetMethod(),
                                                             throw_location.GetDexPc());
      if (method != NULL) {
        // NPE with precise message.
        ThrowNullPointerExceptionForMethodAccess(throw_location, method, kVirtual);
      } else {
        // NPE with imprecise message.
        ThrowNullPointerException(&throw_location,
                                  "Attempt to invoke a virtual method on a null object reference");
      }
      break;
    }
    case Instruction::IGET:
    case Instruction::IGET_WIDE:
    case Instruction::IGET_OBJECT:
    case Instruction::IGET_BOOLEAN:
    case Instruction::IGET_BYTE:
    case Instruction::IGET_CHAR:
    case Instruction::IGET_SHORT: {
      mirror::Field* field =
          Runtime::Current()->GetClassLinker()->ResolveField(instr->VRegC_22c(),
                                                             throw_location.GetMethod(), false);
      ThrowNullPointerExceptionForFieldAccess(throw_location, field, true /* read */);
      break;
    }
    case Instruction::IGET_QUICK:
    case Instruction::IGET_WIDE_QUICK:
    case Instruction::IGET_OBJECT_QUICK: {
      // Since we replaced the field index, we ask the verifier to tell us which
      // field is accessed at this location.
      mirror::Field* field =
          verifier::MethodVerifier::FindAccessedFieldAtDexPc(throw_location.GetMethod(),
                                                             throw_location.GetDexPc());
      if (field != NULL) {
        // NPE with precise message.
        ThrowNullPointerExceptionForFieldAccess(throw_location, field, true /* read */);
      } else {
        // NPE with imprecise message.
        ThrowNullPointerException(&throw_location,
                                  "Attempt to read from a field on a null object reference");
      }
      break;
    }
    case Instruction::IPUT:
    case Instruction::IPUT_WIDE:
    case Instruction::IPUT_OBJECT:
    case Instruction::IPUT_BOOLEAN:
    case Instruction::IPUT_BYTE:
    case Instruction::IPUT_CHAR:
    case Instruction::IPUT_SHORT: {
      mirror::Field* field =
          Runtime::Current()->GetClassLinker()->ResolveField(instr->VRegC_22c(),
                                                             throw_location.GetMethod(), false);
      ThrowNullPointerExceptionForFieldAccess(throw_location, field, false /* write */);
      break;
    }
    case Instruction::IPUT_QUICK:
    case Instruction::IPUT_WIDE_QUICK:
    case Instruction::IPUT_OBJECT_QUICK: {
      // Since we replaced the field index, we ask the verifier to tell us which
      // field is accessed at this location.
      mirror::Field* field =
          verifier::MethodVerifier::FindAccessedFieldAtDexPc(throw_location.GetMethod(),
                                                             throw_location.GetDexPc());
      if (field != NULL) {
        // NPE with precise message.
        ThrowNullPointerExceptionForFieldAccess(throw_location, field, false /* write */);
      } else {
        // NPE with imprecise message.
        ThrowNullPointerException(&throw_location,
                                  "Attempt to write to a field on a null object reference");
      }
      break;
    }
    case Instruction::AGET:
    case Instruction::AGET_WIDE:
    case Instruction::AGET_OBJECT:
    case Instruction::AGET_BOOLEAN:
    case Instruction::AGET_BYTE:
    case Instruction::AGET_CHAR:
    case Instruction::AGET_SHORT:
      ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL,
                     "Attempt to read from null array");
      break;
    case Instruction::APUT:
    case Instruction::APUT_WIDE:
    case Instruction::APUT_OBJECT:
    case Instruction::APUT_BOOLEAN:
    case Instruction::APUT_BYTE:
    case Instruction::APUT_CHAR:
    case Instruction::APUT_SHORT:
      ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL,
                     "Attempt to write to null array");
      break;
    case Instruction::ARRAY_LENGTH:
      ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL,
                     "Attempt to get length of null array");
      break;
    default: {
      // TODO: We should have covered all the cases where we expect a NPE above, this
      //       message/logging is so we can improve any cases we've missed in the future.
      const DexFile& dex_file =
          *throw_location.GetMethod()->GetDeclaringClass()->GetDexCache()->GetDexFile();
      ThrowException(&throw_location, "Ljava/lang/NullPointerException;", NULL,
                     StringPrintf("Null pointer exception during instruction '%s'",
                                  instr->DumpString(&dex_file).c_str()).c_str());
      break;
    }
  }
}

void ThrowNullPointerException(const ThrowLocation* throw_location, const char* msg) {
  ThrowException(throw_location, "Ljava/lang/NullPointerException;", NULL, msg);
}

// RuntimeException

void ThrowRuntimeException(const char* fmt, ...) {
  va_list args;
  va_start(args, fmt);
  ThrowException(NULL, "Ljava/lang/RuntimeException;", NULL, fmt, &args);
  va_end(args);
}

// VerifyError

void ThrowVerifyError(const mirror::Class* referrer, const char* fmt, ...) {
  va_list args;
  va_start(args, fmt);
  ThrowException(NULL, "Ljava/lang/VerifyError;", referrer, fmt, &args);
  va_end(args);
}

}  // namespace art
