// Copyright 2008-2009 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.

#ifdef V8_INTERPRETED_REGEXP

#include "src/regexp/regexp-macro-assembler-irregexp.h"

#include "src/ast/ast.h"
#include "src/objects-inl.h"
#include "src/regexp/bytecodes-irregexp.h"
#include "src/regexp/regexp-macro-assembler-irregexp-inl.h"
#include "src/regexp/regexp-macro-assembler.h"

namespace v8 {
namespace internal {

RegExpMacroAssemblerIrregexp::RegExpMacroAssemblerIrregexp(Isolate* isolate,
                                                           Vector<byte> buffer,
                                                           Zone* zone)
    : RegExpMacroAssembler(isolate, zone),
      buffer_(buffer),
      pc_(0),
      own_buffer_(false),
      advance_current_end_(kInvalidPC),
      isolate_(isolate) {}


RegExpMacroAssemblerIrregexp::~RegExpMacroAssemblerIrregexp() {
  if (backtrack_.is_linked()) backtrack_.Unuse();
  if (own_buffer_) buffer_.Dispose();
}


RegExpMacroAssemblerIrregexp::IrregexpImplementation
RegExpMacroAssemblerIrregexp::Implementation() {
  return kBytecodeImplementation;
}


void RegExpMacroAssemblerIrregexp::Bind(Label* l) {
  advance_current_end_ = kInvalidPC;
  DCHECK(!l->is_bound());
  if (l->is_linked()) {
    int pos = l->pos();
    while (pos != 0) {
      int fixup = pos;
      pos = *reinterpret_cast<int32_t*>(buffer_.start() + fixup);
      *reinterpret_cast<uint32_t*>(buffer_.start() + fixup) = pc_;
    }
  }
  l->bind_to(pc_);
}


void RegExpMacroAssemblerIrregexp::EmitOrLink(Label* l) {
  if (l == NULL) l = &backtrack_;
  if (l->is_bound()) {
    Emit32(l->pos());
  } else {
    int pos = 0;
    if (l->is_linked()) {
      pos = l->pos();
    }
    l->link_to(pc_);
    Emit32(pos);
  }
}


void RegExpMacroAssemblerIrregexp::PopRegister(int register_index) {
  DCHECK(register_index >= 0);
  DCHECK(register_index <= kMaxRegister);
  Emit(BC_POP_REGISTER, register_index);
}


void RegExpMacroAssemblerIrregexp::PushRegister(
    int register_index,
    StackCheckFlag check_stack_limit) {
  DCHECK(register_index >= 0);
  DCHECK(register_index <= kMaxRegister);
  Emit(BC_PUSH_REGISTER, register_index);
}


void RegExpMacroAssemblerIrregexp::WriteCurrentPositionToRegister(
    int register_index, int cp_offset) {
  DCHECK(register_index >= 0);
  DCHECK(register_index <= kMaxRegister);
  Emit(BC_SET_REGISTER_TO_CP, register_index);
  Emit32(cp_offset);  // Current position offset.
}


void RegExpMacroAssemblerIrregexp::ClearRegisters(int reg_from, int reg_to) {
  DCHECK(reg_from <= reg_to);
  for (int reg = reg_from; reg <= reg_to; reg++) {
    SetRegister(reg, -1);
  }
}


void RegExpMacroAssemblerIrregexp::ReadCurrentPositionFromRegister(
    int register_index) {
  DCHECK(register_index >= 0);
  DCHECK(register_index <= kMaxRegister);
  Emit(BC_SET_CP_TO_REGISTER, register_index);
}


void RegExpMacroAssemblerIrregexp::WriteStackPointerToRegister(
    int register_index) {
  DCHECK(register_index >= 0);
  DCHECK(register_index <= kMaxRegister);
  Emit(BC_SET_REGISTER_TO_SP, register_index);
}


void RegExpMacroAssemblerIrregexp::ReadStackPointerFromRegister(
    int register_index) {
  DCHECK(register_index >= 0);
  DCHECK(register_index <= kMaxRegister);
  Emit(BC_SET_SP_TO_REGISTER, register_index);
}


void RegExpMacroAssemblerIrregexp::SetCurrentPositionFromEnd(int by) {
  DCHECK(is_uint24(by));
  Emit(BC_SET_CURRENT_POSITION_FROM_END, by);
}


void RegExpMacroAssemblerIrregexp::SetRegister(int register_index, int to) {
  DCHECK(register_index >= 0);
  DCHECK(register_index <= kMaxRegister);
  Emit(BC_SET_REGISTER, register_index);
  Emit32(to);
}


void RegExpMacroAssemblerIrregexp::AdvanceRegister(int register_index, int by) {
  DCHECK(register_index >= 0);
  DCHECK(register_index <= kMaxRegister);
  Emit(BC_ADVANCE_REGISTER, register_index);
  Emit32(by);
}


void RegExpMacroAssemblerIrregexp::PopCurrentPosition() {
  Emit(BC_POP_CP, 0);
}


void RegExpMacroAssemblerIrregexp::PushCurrentPosition() {
  Emit(BC_PUSH_CP, 0);
}


void RegExpMacroAssemblerIrregexp::Backtrack() {
  Emit(BC_POP_BT, 0);
}


void RegExpMacroAssemblerIrregexp::GoTo(Label* l) {
  if (advance_current_end_ == pc_) {
    // Combine advance current and goto.
    pc_ = advance_current_start_;
    Emit(BC_ADVANCE_CP_AND_GOTO, advance_current_offset_);
    EmitOrLink(l);
    advance_current_end_ = kInvalidPC;
  } else {
    // Regular goto.
    Emit(BC_GOTO, 0);
    EmitOrLink(l);
  }
}


void RegExpMacroAssemblerIrregexp::PushBacktrack(Label* l) {
  Emit(BC_PUSH_BT, 0);
  EmitOrLink(l);
}


bool RegExpMacroAssemblerIrregexp::Succeed() {
  Emit(BC_SUCCEED, 0);
  return false;  // Restart matching for global regexp not supported.
}


void RegExpMacroAssemblerIrregexp::Fail() {
  Emit(BC_FAIL, 0);
}


void RegExpMacroAssemblerIrregexp::AdvanceCurrentPosition(int by) {
  DCHECK(by >= kMinCPOffset);
  DCHECK(by <= kMaxCPOffset);
  advance_current_start_ = pc_;
  advance_current_offset_ = by;
  Emit(BC_ADVANCE_CP, by);
  advance_current_end_ = pc_;
}


void RegExpMacroAssemblerIrregexp::CheckGreedyLoop(
      Label* on_tos_equals_current_position) {
  Emit(BC_CHECK_GREEDY, 0);
  EmitOrLink(on_tos_equals_current_position);
}


void RegExpMacroAssemblerIrregexp::LoadCurrentCharacter(int cp_offset,
                                                        Label* on_failure,
                                                        bool check_bounds,
                                                        int characters) {
  DCHECK(cp_offset >= kMinCPOffset);
  DCHECK(cp_offset <= kMaxCPOffset);
  int bytecode;
  if (check_bounds) {
    if (characters == 4) {
      bytecode = BC_LOAD_4_CURRENT_CHARS;
    } else if (characters == 2) {
      bytecode = BC_LOAD_2_CURRENT_CHARS;
    } else {
      DCHECK(characters == 1);
      bytecode = BC_LOAD_CURRENT_CHAR;
    }
  } else {
    if (characters == 4) {
      bytecode = BC_LOAD_4_CURRENT_CHARS_UNCHECKED;
    } else if (characters == 2) {
      bytecode = BC_LOAD_2_CURRENT_CHARS_UNCHECKED;
    } else {
      DCHECK(characters == 1);
      bytecode = BC_LOAD_CURRENT_CHAR_UNCHECKED;
    }
  }
  Emit(bytecode, cp_offset);
  if (check_bounds) EmitOrLink(on_failure);
}


void RegExpMacroAssemblerIrregexp::CheckCharacterLT(uc16 limit,
                                                    Label* on_less) {
  Emit(BC_CHECK_LT, limit);
  EmitOrLink(on_less);
}


void RegExpMacroAssemblerIrregexp::CheckCharacterGT(uc16 limit,
                                                    Label* on_greater) {
  Emit(BC_CHECK_GT, limit);
  EmitOrLink(on_greater);
}


void RegExpMacroAssemblerIrregexp::CheckCharacter(uint32_t c, Label* on_equal) {
  if (c > MAX_FIRST_ARG) {
    Emit(BC_CHECK_4_CHARS, 0);
    Emit32(c);
  } else {
    Emit(BC_CHECK_CHAR, c);
  }
  EmitOrLink(on_equal);
}


void RegExpMacroAssemblerIrregexp::CheckAtStart(Label* on_at_start) {
  Emit(BC_CHECK_AT_START, 0);
  EmitOrLink(on_at_start);
}


void RegExpMacroAssemblerIrregexp::CheckNotAtStart(int cp_offset,
                                                   Label* on_not_at_start) {
  Emit(BC_CHECK_NOT_AT_START, cp_offset);
  EmitOrLink(on_not_at_start);
}


void RegExpMacroAssemblerIrregexp::CheckNotCharacter(uint32_t c,
                                                     Label* on_not_equal) {
  if (c > MAX_FIRST_ARG) {
    Emit(BC_CHECK_NOT_4_CHARS, 0);
    Emit32(c);
  } else {
    Emit(BC_CHECK_NOT_CHAR, c);
  }
  EmitOrLink(on_not_equal);
}


void RegExpMacroAssemblerIrregexp::CheckCharacterAfterAnd(
    uint32_t c,
    uint32_t mask,
    Label* on_equal) {
  if (c > MAX_FIRST_ARG) {
    Emit(BC_AND_CHECK_4_CHARS, 0);
    Emit32(c);
  } else {
    Emit(BC_AND_CHECK_CHAR, c);
  }
  Emit32(mask);
  EmitOrLink(on_equal);
}


void RegExpMacroAssemblerIrregexp::CheckNotCharacterAfterAnd(
    uint32_t c,
    uint32_t mask,
    Label* on_not_equal) {
  if (c > MAX_FIRST_ARG) {
    Emit(BC_AND_CHECK_NOT_4_CHARS, 0);
    Emit32(c);
  } else {
    Emit(BC_AND_CHECK_NOT_CHAR, c);
  }
  Emit32(mask);
  EmitOrLink(on_not_equal);
}


void RegExpMacroAssemblerIrregexp::CheckNotCharacterAfterMinusAnd(
    uc16 c,
    uc16 minus,
    uc16 mask,
    Label* on_not_equal) {
  Emit(BC_MINUS_AND_CHECK_NOT_CHAR, c);
  Emit16(minus);
  Emit16(mask);
  EmitOrLink(on_not_equal);
}


void RegExpMacroAssemblerIrregexp::CheckCharacterInRange(
    uc16 from,
    uc16 to,
    Label* on_in_range) {
  Emit(BC_CHECK_CHAR_IN_RANGE, 0);
  Emit16(from);
  Emit16(to);
  EmitOrLink(on_in_range);
}


void RegExpMacroAssemblerIrregexp::CheckCharacterNotInRange(
    uc16 from,
    uc16 to,
    Label* on_not_in_range) {
  Emit(BC_CHECK_CHAR_NOT_IN_RANGE, 0);
  Emit16(from);
  Emit16(to);
  EmitOrLink(on_not_in_range);
}


void RegExpMacroAssemblerIrregexp::CheckBitInTable(
    Handle<ByteArray> table, Label* on_bit_set) {
  Emit(BC_CHECK_BIT_IN_TABLE, 0);
  EmitOrLink(on_bit_set);
  for (int i = 0; i < kTableSize; i += kBitsPerByte) {
    int byte = 0;
    for (int j = 0; j < kBitsPerByte; j++) {
      if (table->get(i + j) != 0) byte |= 1 << j;
    }
    Emit8(byte);
  }
}


void RegExpMacroAssemblerIrregexp::CheckNotBackReference(int start_reg,
                                                         bool read_backward,
                                                         Label* on_not_equal) {
  DCHECK(start_reg >= 0);
  DCHECK(start_reg <= kMaxRegister);
  Emit(read_backward ? BC_CHECK_NOT_BACK_REF_BACKWARD : BC_CHECK_NOT_BACK_REF,
       start_reg);
  EmitOrLink(on_not_equal);
}


void RegExpMacroAssemblerIrregexp::CheckNotBackReferenceIgnoreCase(
    int start_reg, bool read_backward, bool unicode, Label* on_not_equal) {
  DCHECK(start_reg >= 0);
  DCHECK(start_reg <= kMaxRegister);
  Emit(read_backward ? (unicode ? BC_CHECK_NOT_BACK_REF_NO_CASE_UNICODE_BACKWARD
                                : BC_CHECK_NOT_BACK_REF_NO_CASE_BACKWARD)
                     : (unicode ? BC_CHECK_NOT_BACK_REF_NO_CASE_UNICODE
                                : BC_CHECK_NOT_BACK_REF_NO_CASE),
       start_reg);
  EmitOrLink(on_not_equal);
}


void RegExpMacroAssemblerIrregexp::IfRegisterLT(int register_index,
                                                int comparand,
                                                Label* on_less_than) {
  DCHECK(register_index >= 0);
  DCHECK(register_index <= kMaxRegister);
  Emit(BC_CHECK_REGISTER_LT, register_index);
  Emit32(comparand);
  EmitOrLink(on_less_than);
}


void RegExpMacroAssemblerIrregexp::IfRegisterGE(int register_index,
                                                int comparand,
                                                Label* on_greater_or_equal) {
  DCHECK(register_index >= 0);
  DCHECK(register_index <= kMaxRegister);
  Emit(BC_CHECK_REGISTER_GE, register_index);
  Emit32(comparand);
  EmitOrLink(on_greater_or_equal);
}


void RegExpMacroAssemblerIrregexp::IfRegisterEqPos(int register_index,
                                                   Label* on_eq) {
  DCHECK(register_index >= 0);
  DCHECK(register_index <= kMaxRegister);
  Emit(BC_CHECK_REGISTER_EQ_POS, register_index);
  EmitOrLink(on_eq);
}


Handle<HeapObject> RegExpMacroAssemblerIrregexp::GetCode(
    Handle<String> source) {
  Bind(&backtrack_);
  Emit(BC_POP_BT, 0);
  Handle<ByteArray> array = isolate_->factory()->NewByteArray(length());
  Copy(array->GetDataStartAddress());
  return array;
}


int RegExpMacroAssemblerIrregexp::length() {
  return pc_;
}


void RegExpMacroAssemblerIrregexp::Copy(Address a) {
  MemCopy(a, buffer_.start(), length());
}


void RegExpMacroAssemblerIrregexp::Expand() {
  bool old_buffer_was_our_own = own_buffer_;
  Vector<byte> old_buffer = buffer_;
  buffer_ = Vector<byte>::New(old_buffer.length() * 2);
  own_buffer_ = true;
  MemCopy(buffer_.start(), old_buffer.start(), old_buffer.length());
  if (old_buffer_was_our_own) {
    old_buffer.Dispose();
  }
}

}  // namespace internal
}  // namespace v8

#endif  // V8_INTERPRETED_REGEXP
