// 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>
#include <cstdarg>
#include <cstdio>
#include <cstdlib>

#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;

std::string PrettyPrintChar(int ch) {
  std::ostringstream oss;
  switch (ch) {
#define CHAR_PRINT_CASE(ch) \
  case ch:                  \
    oss << #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)) {
        oss << '\'' << ch << '\'';
      } else {
        oss << std::hex << "\\x" << static_cast<unsigned int>(ch);
      }
  }
  return oss.str();
}

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 <>                                                    \
  std::string PrintCheckOperand<type>(type ch) {                 \
    return PrettyPrintChar(ch);                                  \
  }                                                              \
  template <>                                                    \
  std::string PrintCheckOperand<type*>(type * cstr) {            \
    return PrintCheckOperand<void*>(cstr);                       \
  }                                                              \
  template <>                                                    \
  std::string PrintCheckOperand<const type*>(const type* cstr) { \
    return PrintCheckOperand<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 std::string PrintCheckOperand<type>(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

}  // 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);

  fflush(stdout);
  fflush(stderr);
  // 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();

  fflush(stderr);
  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);
}
