// Copyright 2008 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "v8.h"
#include "ast.h"
#include "regexp-macro-assembler.h"
#include "regexp-macro-assembler-tracer.h"

namespace v8 {
namespace internal {

RegExpMacroAssemblerTracer::RegExpMacroAssemblerTracer(
    RegExpMacroAssembler* assembler) :
  assembler_(assembler) {
  unsigned int type = assembler->Implementation();
  ASSERT(type < 4);
  const char* impl_names[4] = {"IA32", "ARM", "X64", "Bytecode"};
  PrintF("RegExpMacroAssembler%s();\n", impl_names[type]);
}


RegExpMacroAssemblerTracer::~RegExpMacroAssemblerTracer() {
}


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


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


void RegExpMacroAssemblerTracer::Fail() {
  PrintF(" Fail();\n");
  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);
}


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


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


void RegExpMacroAssemblerTracer::CheckCharacter(unsigned c, Label* on_equal) {
  PrintF(" CheckCharacter(c='u%04x', label[%08x]);\n",
         c, 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(Label* on_not_at_start) {
  PrintF(" CheckNotAtStart(label[%08x]);\n", LabelToInt(on_not_at_start));
  assembler_->CheckNotAtStart(on_not_at_start);
}


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


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


void RegExpMacroAssemblerTracer::CheckNotCharacterAfterAnd(
    unsigned c,
    unsigned mask,
    Label* on_not_equal) {
  PrintF(" CheckNotCharacterAfterAnd(c='u%04x', mask=0x%04x, label[%08x]);\n",
         c,
         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='u%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::CheckNotBackReference(int start_reg,
                                                       Label* on_no_match) {
  PrintF(" CheckNotBackReference(register=%d, label[%08x]);\n", start_reg,
         LabelToInt(on_no_match));
  assembler_->CheckNotBackReference(start_reg, on_no_match);
}


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


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


void RegExpMacroAssemblerTracer::CheckCharacters(Vector<const uc16> str,
                                                 int cp_offset,
                                                 Label* on_failure,
                                                 bool check_end_of_string) {
  PrintF(" %s(str=\"",
         check_end_of_string ? "CheckCharacters" : "CheckCharactersUnchecked");
  for (int i = 0; i < str.length(); i++) {
    PrintF("u%04x", str[i]);
  }
  PrintF("\", cp_offset=%d, label[%08x])\n",
         cp_offset, LabelToInt(on_failure));
  assembler_->CheckCharacters(str, cp_offset, on_failure, check_end_of_string);
}


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()));
  return assembler_->GetCode(source);
}

}}  // namespace v8::internal
