// Copyright 2012 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/regexp/regexp-macro-assembler-tracer.h"

#include "src/ast/ast.h"
#include "src/objects/objects-inl.h"

namespace v8 {
namespace internal {

RegExpMacroAssemblerTracer::RegExpMacroAssemblerTracer(
    Isolate* isolate, RegExpMacroAssembler* assembler)
    : RegExpMacroAssembler(isolate, assembler->zone()), assembler_(assembler) {
  IrregexpImplementation type = assembler->Implementation();
  DCHECK_LT(type, 9);
  const char* impl_names[] = {"IA32", "ARM", "ARM64", "MIPS",    "S390",
                              "PPC",  "X64", "X87",   "Bytecode"};
  PrintF("RegExpMacroAssembler%s();\n", impl_names[type]);
}

RegExpMacroAssemblerTracer::~RegExpMacroAssemblerTracer() = default;

void RegExpMacroAssemblerTracer::AbortedCodeGeneration() {
  PrintF(" AbortedCodeGeneration\n");
  assembler_->AbortedCodeGeneration();
}


// This is used for printing out debugging information.  It makes an integer
// that is closely related to the address of an object.
static int LabelToInt(Label* label) {
  return static_cast<int>(reinterpret_cast<intptr_t>(label));
}


void RegExpMacroAssemblerTracer::Bind(Label* label) {
  PrintF("label[%08x]: (Bind)\n", LabelToInt(label));
  assembler_->Bind(label);
}


void RegExpMacroAssemblerTracer::AdvanceCurrentPosition(int by) {
  PrintF(" AdvanceCurrentPosition(by=%d);\n", by);
  assembler_->AdvanceCurrentPosition(by);
}


void RegExpMacroAssemblerTracer::CheckGreedyLoop(Label* label) {
  PrintF(" CheckGreedyLoop(label[%08x]);\n\n", LabelToInt(label));
  assembler_->CheckGreedyLoop(label);
}


void RegExpMacroAssemblerTracer::PopCurrentPosition() {
  PrintF(" PopCurrentPosition();\n");
  assembler_->PopCurrentPosition();
}


void RegExpMacroAssemblerTracer::PushCurrentPosition() {
  PrintF(" PushCurrentPosition();\n");
  assembler_->PushCurrentPosition();
}


void RegExpMacroAssemblerTracer::Backtrack() {
  PrintF(" Backtrack();\n");
  assembler_->Backtrack();
}


void RegExpMacroAssemblerTracer::GoTo(Label* label) {
  PrintF(" GoTo(label[%08x]);\n\n", LabelToInt(label));
  assembler_->GoTo(label);
}


void RegExpMacroAssemblerTracer::PushBacktrack(Label* label) {
  PrintF(" PushBacktrack(label[%08x]);\n", LabelToInt(label));
  assembler_->PushBacktrack(label);
}


bool RegExpMacroAssemblerTracer::Succeed() {
  bool restart = assembler_->Succeed();
  PrintF(" Succeed();%s\n", restart ? " [restart for global match]" : "");
  return restart;
}


void RegExpMacroAssemblerTracer::Fail() {
  PrintF(" Fail();");
  assembler_->Fail();
}


void RegExpMacroAssemblerTracer::PopRegister(int register_index) {
  PrintF(" PopRegister(register=%d);\n", register_index);
  assembler_->PopRegister(register_index);
}


void RegExpMacroAssemblerTracer::PushRegister(
    int register_index,
    StackCheckFlag check_stack_limit) {
  PrintF(" PushRegister(register=%d, %s);\n",
         register_index,
         check_stack_limit ? "check stack limit" : "");
  assembler_->PushRegister(register_index, check_stack_limit);
}


void RegExpMacroAssemblerTracer::AdvanceRegister(int reg, int by) {
  PrintF(" AdvanceRegister(register=%d, by=%d);\n", reg, by);
  assembler_->AdvanceRegister(reg, by);
}


void RegExpMacroAssemblerTracer::SetCurrentPositionFromEnd(int by) {
  PrintF(" SetCurrentPositionFromEnd(by=%d);\n", by);
  assembler_->SetCurrentPositionFromEnd(by);
}


void RegExpMacroAssemblerTracer::SetRegister(int register_index, int to) {
  PrintF(" SetRegister(register=%d, to=%d);\n", register_index, to);
  assembler_->SetRegister(register_index, to);
}


void RegExpMacroAssemblerTracer::WriteCurrentPositionToRegister(int reg,
                                                                int cp_offset) {
  PrintF(" WriteCurrentPositionToRegister(register=%d,cp_offset=%d);\n",
         reg,
         cp_offset);
  assembler_->WriteCurrentPositionToRegister(reg, cp_offset);
}


void RegExpMacroAssemblerTracer::ClearRegisters(int reg_from, int reg_to) {
  PrintF(" ClearRegister(from=%d, to=%d);\n", reg_from, reg_to);
  assembler_->ClearRegisters(reg_from, reg_to);
}


void RegExpMacroAssemblerTracer::ReadCurrentPositionFromRegister(int reg) {
  PrintF(" ReadCurrentPositionFromRegister(register=%d);\n", reg);
  assembler_->ReadCurrentPositionFromRegister(reg);
}


void RegExpMacroAssemblerTracer::WriteStackPointerToRegister(int reg) {
  PrintF(" WriteStackPointerToRegister(register=%d);\n", reg);
  assembler_->WriteStackPointerToRegister(reg);
}


void RegExpMacroAssemblerTracer::ReadStackPointerFromRegister(int reg) {
  PrintF(" ReadStackPointerFromRegister(register=%d);\n", reg);
  assembler_->ReadStackPointerFromRegister(reg);
}


void RegExpMacroAssemblerTracer::LoadCurrentCharacter(int cp_offset,
                                                      Label* on_end_of_input,
                                                      bool check_bounds,
                                                      int characters) {
  const char* check_msg = check_bounds ? "" : " (unchecked)";
  PrintF(" LoadCurrentCharacter(cp_offset=%d, label[%08x]%s (%d chars));\n",
         cp_offset,
         LabelToInt(on_end_of_input),
         check_msg,
         characters);
  assembler_->LoadCurrentCharacter(cp_offset,
                                   on_end_of_input,
                                   check_bounds,
                                   characters);
}


class PrintablePrinter {
 public:
  explicit PrintablePrinter(uc16 character) : character_(character) { }

  const char* operator*() {
    if (character_ >= ' ' && character_ <= '~') {
      buffer_[0] = '(';
      buffer_[1] = static_cast<char>(character_);
      buffer_[2] = ')';
      buffer_[3] = '\0';
    } else {
      buffer_[0] = '\0';
    }
    return &buffer_[0];
  }

 private:
  uc16 character_;
  char buffer_[4];
};


void RegExpMacroAssemblerTracer::CheckCharacterLT(uc16 limit, Label* on_less) {
  PrintablePrinter printable(limit);
  PrintF(" CheckCharacterLT(c=0x%04x%s, label[%08x]);\n",
         limit,
         *printable,
         LabelToInt(on_less));
  assembler_->CheckCharacterLT(limit, on_less);
}


void RegExpMacroAssemblerTracer::CheckCharacterGT(uc16 limit,
                                                  Label* on_greater) {
  PrintablePrinter printable(limit);
  PrintF(" CheckCharacterGT(c=0x%04x%s, label[%08x]);\n",
         limit,
         *printable,
         LabelToInt(on_greater));
  assembler_->CheckCharacterGT(limit, on_greater);
}


void RegExpMacroAssemblerTracer::CheckCharacter(unsigned c, Label* on_equal) {
  PrintablePrinter printable(c);
  PrintF(" CheckCharacter(c=0x%04x%s, label[%08x]);\n",
         c,
         *printable,
         LabelToInt(on_equal));
  assembler_->CheckCharacter(c, on_equal);
}


void RegExpMacroAssemblerTracer::CheckAtStart(Label* on_at_start) {
  PrintF(" CheckAtStart(label[%08x]);\n", LabelToInt(on_at_start));
  assembler_->CheckAtStart(on_at_start);
}


void RegExpMacroAssemblerTracer::CheckNotAtStart(int cp_offset,
                                                 Label* on_not_at_start) {
  PrintF(" CheckNotAtStart(cp_offset=%d, label[%08x]);\n", cp_offset,
         LabelToInt(on_not_at_start));
  assembler_->CheckNotAtStart(cp_offset, on_not_at_start);
}


void RegExpMacroAssemblerTracer::CheckNotCharacter(unsigned c,
                                                   Label* on_not_equal) {
  PrintablePrinter printable(c);
  PrintF(" CheckNotCharacter(c=0x%04x%s, label[%08x]);\n",
         c,
         *printable,
         LabelToInt(on_not_equal));
  assembler_->CheckNotCharacter(c, on_not_equal);
}


void RegExpMacroAssemblerTracer::CheckCharacterAfterAnd(
    unsigned c,
    unsigned mask,
    Label* on_equal) {
  PrintablePrinter printable(c);
  PrintF(" CheckCharacterAfterAnd(c=0x%04x%s, mask=0x%04x, label[%08x]);\n",
         c,
         *printable,
         mask,
         LabelToInt(on_equal));
  assembler_->CheckCharacterAfterAnd(c, mask, on_equal);
}


void RegExpMacroAssemblerTracer::CheckNotCharacterAfterAnd(
    unsigned c,
    unsigned mask,
    Label* on_not_equal) {
  PrintablePrinter printable(c);
  PrintF(" CheckNotCharacterAfterAnd(c=0x%04x%s, mask=0x%04x, label[%08x]);\n",
         c,
         *printable,
         mask,
         LabelToInt(on_not_equal));
  assembler_->CheckNotCharacterAfterAnd(c, mask, on_not_equal);
}


void RegExpMacroAssemblerTracer::CheckNotCharacterAfterMinusAnd(
    uc16 c,
    uc16 minus,
    uc16 mask,
    Label* on_not_equal) {
  PrintF(" CheckNotCharacterAfterMinusAnd(c=0x%04x, minus=%04x, mask=0x%04x, "
             "label[%08x]);\n",
         c,
         minus,
         mask,
         LabelToInt(on_not_equal));
  assembler_->CheckNotCharacterAfterMinusAnd(c, minus, mask, on_not_equal);
}


void RegExpMacroAssemblerTracer::CheckCharacterInRange(
    uc16 from,
    uc16 to,
    Label* on_not_in_range) {
  PrintablePrinter printable_from(from);
  PrintablePrinter printable_to(to);
  PrintF(" CheckCharacterInRange(from=0x%04x%s, to=0x%04x%s, label[%08x]);\n",
         from,
         *printable_from,
         to,
         *printable_to,
         LabelToInt(on_not_in_range));
  assembler_->CheckCharacterInRange(from, to, on_not_in_range);
}


void RegExpMacroAssemblerTracer::CheckCharacterNotInRange(
    uc16 from,
    uc16 to,
    Label* on_in_range) {
  PrintablePrinter printable_from(from);
  PrintablePrinter printable_to(to);
  PrintF(
      " CheckCharacterNotInRange(from=0x%04x%s," " to=%04x%s, label[%08x]);\n",
      from,
      *printable_from,
      to,
      *printable_to,
      LabelToInt(on_in_range));
  assembler_->CheckCharacterNotInRange(from, to, on_in_range);
}


void RegExpMacroAssemblerTracer::CheckBitInTable(
    Handle<ByteArray> table, Label* on_bit_set) {
  PrintF(" CheckBitInTable(label[%08x] ", LabelToInt(on_bit_set));
  for (int i = 0; i < kTableSize; i++) {
    PrintF("%c", table->get(i) != 0 ? 'X' : '.');
    if (i % 32 == 31 && i != kTableMask) {
      PrintF("\n                                 ");
    }
  }
  PrintF(");\n");
  assembler_->CheckBitInTable(table, on_bit_set);
}


void RegExpMacroAssemblerTracer::CheckNotBackReference(int start_reg,
                                                       bool read_backward,
                                                       Label* on_no_match) {
  PrintF(" CheckNotBackReference(register=%d, %s, label[%08x]);\n", start_reg,
         read_backward ? "backward" : "forward", LabelToInt(on_no_match));
  assembler_->CheckNotBackReference(start_reg, read_backward, on_no_match);
}


void RegExpMacroAssemblerTracer::CheckNotBackReferenceIgnoreCase(
    int start_reg, bool read_backward, bool unicode, Label* on_no_match) {
  PrintF(" CheckNotBackReferenceIgnoreCase(register=%d, %s %s, label[%08x]);\n",
         start_reg, read_backward ? "backward" : "forward",
         unicode ? "unicode" : "non-unicode", LabelToInt(on_no_match));
  assembler_->CheckNotBackReferenceIgnoreCase(start_reg, read_backward, unicode,
                                              on_no_match);
}


void RegExpMacroAssemblerTracer::CheckPosition(int cp_offset,
                                               Label* on_outside_input) {
  PrintF(" CheckPosition(cp_offset=%d, label[%08x]);\n", cp_offset,
         LabelToInt(on_outside_input));
  assembler_->CheckPosition(cp_offset, on_outside_input);
}


bool RegExpMacroAssemblerTracer::CheckSpecialCharacterClass(
    uc16 type,
    Label* on_no_match) {
  bool supported = assembler_->CheckSpecialCharacterClass(type,
                                                          on_no_match);
  PrintF(" CheckSpecialCharacterClass(type='%c', label[%08x]): %s;\n",
         type,
         LabelToInt(on_no_match),
         supported ? "true" : "false");
  return supported;
}


void RegExpMacroAssemblerTracer::IfRegisterLT(int register_index,
                                              int comparand, Label* if_lt) {
  PrintF(" IfRegisterLT(register=%d, number=%d, label[%08x]);\n",
         register_index, comparand, LabelToInt(if_lt));
  assembler_->IfRegisterLT(register_index, comparand, if_lt);
}


void RegExpMacroAssemblerTracer::IfRegisterEqPos(int register_index,
                                                 Label* if_eq) {
  PrintF(" IfRegisterEqPos(register=%d, label[%08x]);\n",
         register_index, LabelToInt(if_eq));
  assembler_->IfRegisterEqPos(register_index, if_eq);
}


void RegExpMacroAssemblerTracer::IfRegisterGE(int register_index,
                                              int comparand, Label* if_ge) {
  PrintF(" IfRegisterGE(register=%d, number=%d, label[%08x]);\n",
         register_index, comparand, LabelToInt(if_ge));
  assembler_->IfRegisterGE(register_index, comparand, if_ge);
}


RegExpMacroAssembler::IrregexpImplementation
    RegExpMacroAssemblerTracer::Implementation() {
  return assembler_->Implementation();
}


Handle<HeapObject> RegExpMacroAssemblerTracer::GetCode(Handle<String> source) {
  PrintF(" GetCode(%s);\n", source->ToCString().get());
  return assembler_->GetCode(source);
}

}  // namespace internal
}  // namespace v8
