// Copyright 2006-2008 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/base/logging.h"

#include <cctype>
#if !V8_OS_STARBOARD
#include <cstdarg>
#include <cstdio>
#include <cstdlib>
#endif

#include "src/base/debug/stack_trace.h"
#include "src/base/platform/platform.h"

namespace v8 {
namespace base {

namespace {

void DefaultDcheckHandler(const char* file, int line, const char* message);

void (*g_print_stack_trace)() = nullptr;

void (*g_dcheck_function)(const char*, int, const char*) = DefaultDcheckHandler;

void PrettyPrintChar(std::ostream& os, int ch) {
  switch (ch) {
#define CHAR_PRINT_CASE(ch) \
  case ch:                  \
    os << #ch;              \
    break;

    CHAR_PRINT_CASE('\0')
    CHAR_PRINT_CASE('\'')
    CHAR_PRINT_CASE('\\')
    CHAR_PRINT_CASE('\a')
    CHAR_PRINT_CASE('\b')
    CHAR_PRINT_CASE('\f')
    CHAR_PRINT_CASE('\n')
    CHAR_PRINT_CASE('\r')
    CHAR_PRINT_CASE('\t')
    CHAR_PRINT_CASE('\v')
#undef CHAR_PRINT_CASE
    default:
      if (std::isprint(ch)) {
        os << '\'' << ch << '\'';
      } else {
        auto flags = os.flags(std::ios_base::hex);
        os << "\\x" << static_cast<unsigned int>(ch);
        os.flags(flags);
      }
  }
}

void DefaultDcheckHandler(const char* file, int line, const char* message) {
#ifdef DEBUG
  V8_Fatal(file, line, "Debug check failed: %s.", message);
#else
  // This case happens only for unit tests.
  V8_Fatal("Debug check failed: %s.", message);
#endif
}

}  // namespace

void SetPrintStackTrace(void (*print_stack_trace)()) {
  g_print_stack_trace = print_stack_trace;
}

void SetDcheckFunction(void (*dcheck_function)(const char*, int, const char*)) {
  g_dcheck_function = dcheck_function ? dcheck_function : &DefaultDcheckHandler;
}

// Define specialization to pretty print characters (escaping non-printable
// characters) and to print c strings as pointers instead of strings.
#define DEFINE_PRINT_CHECK_OPERAND_CHAR(type)                                \
  template <>                                                                \
  void PrintCheckOperand<type>(std::ostream & os, type ch) {                 \
    PrettyPrintChar(os, ch);                                                 \
  }                                                                          \
  template <>                                                                \
  void PrintCheckOperand<type*>(std::ostream & os, type * cstr) {            \
    os << static_cast<void*>(cstr);                                          \
  }                                                                          \
  template <>                                                                \
  void PrintCheckOperand<const type*>(std::ostream & os, const type* cstr) { \
    os << static_cast<const void*>(cstr);                                    \
  }

DEFINE_PRINT_CHECK_OPERAND_CHAR(char)
DEFINE_PRINT_CHECK_OPERAND_CHAR(signed char)
DEFINE_PRINT_CHECK_OPERAND_CHAR(unsigned char)
#undef DEFINE_PRINT_CHECK_OPERAND_CHAR

// Explicit instantiations for commonly used comparisons.
#define DEFINE_MAKE_CHECK_OP_STRING(type)                           \
  template std::string* MakeCheckOpString<type, type>(type, type,   \
                                                      char const*); \
  template void PrintCheckOperand<type>(std::ostream&, type);
DEFINE_MAKE_CHECK_OP_STRING(int)
DEFINE_MAKE_CHECK_OP_STRING(long)       // NOLINT(runtime/int)
DEFINE_MAKE_CHECK_OP_STRING(long long)  // NOLINT(runtime/int)
DEFINE_MAKE_CHECK_OP_STRING(unsigned int)
DEFINE_MAKE_CHECK_OP_STRING(unsigned long)       // NOLINT(runtime/int)
DEFINE_MAKE_CHECK_OP_STRING(unsigned long long)  // NOLINT(runtime/int)
DEFINE_MAKE_CHECK_OP_STRING(void const*)
#undef DEFINE_MAKE_CHECK_OP_STRING


// Explicit instantiations for floating point checks.
#define DEFINE_CHECK_OP_IMPL(NAME)                                            \
  template std::string* Check##NAME##Impl<float, float>(float lhs, float rhs, \
                                                        char const* msg);     \
  template std::string* Check##NAME##Impl<double, double>(                    \
      double lhs, double rhs, char const* msg);
DEFINE_CHECK_OP_IMPL(EQ)
DEFINE_CHECK_OP_IMPL(NE)
DEFINE_CHECK_OP_IMPL(LE)
DEFINE_CHECK_OP_IMPL(LT)
DEFINE_CHECK_OP_IMPL(GE)
DEFINE_CHECK_OP_IMPL(GT)
#undef DEFINE_CHECK_OP_IMPL

}  // namespace base
}  // namespace v8

namespace {

// FailureMessage is a stack allocated object which has a special marker field
// at the start and at the end. This makes it possible to retrieve the embedded
// message from the stack.
//
class FailureMessage {
 public:
  explicit FailureMessage(const char* format, va_list arguments) {
    memset(&message_, 0, arraysize(message_));
    v8::base::OS::VSNPrintF(&message_[0], arraysize(message_), format,
                            arguments);
  }

  static const uintptr_t kStartMarker = 0xdecade10;
  static const uintptr_t kEndMarker = 0xdecade11;
  static const int kMessageBufferSize = 512;

  uintptr_t start_marker_ = kStartMarker;
  char message_[kMessageBufferSize];
  uintptr_t end_marker_ = kEndMarker;
};

}  // namespace

#ifdef DEBUG
void V8_Fatal(const char* file, int line, const char* format, ...) {
#else
void V8_Fatal(const char* format, ...) {
  const char* file = "";
  int line = 0;
#endif
  va_list arguments;
  va_start(arguments, format);
  // Format the error message into a stack object for later retrieveal by the
  // crash processor.
  FailureMessage message(format, arguments);
  va_end(arguments);

#if !V8_OS_STARBOARD
  fflush(stdout);
  fflush(stderr);
#endif
  // Print the formatted message to stdout without cropping the output.
  v8::base::OS::PrintError("\n\n#\n# Fatal error in %s, line %d\n# ", file,
                           line);

  // Print the error message.
  va_start(arguments, format);
  v8::base::OS::VPrintError(format, arguments);
  va_end(arguments);
  // Print the message object's address to force stack allocation.
  v8::base::OS::PrintError("\n#\n#\n#\n#FailureMessage Object: %p", &message);

  if (v8::base::g_print_stack_trace) v8::base::g_print_stack_trace();

#if !V8_OS_STARBOARD
  fflush(stderr);
#endif
  v8::base::OS::Abort();
}

#if !defined(DEBUG) && defined(OFFICIAL_BUILD)
void V8_FatalNoContext() {
  v8::base::OS::PrintError("V8 CHECK or FATAL\n");
  if (v8::base::g_print_stack_trace) v8::base::g_print_stack_trace();
  fflush(stderr);
  v8::base::OS::Abort();
}
#endif

void V8_Dcheck(const char* file, int line, const char* message) {
  v8::base::g_dcheck_function(file, line, message);
}
