// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#if !defined(DART_PRECOMPILED_RUNTIME)

#include "vm/regexp_assembler_ir.h"

#include "vm/bit_vector.h"
#include "vm/compiler/backend/il_printer.h"
#include "vm/compiler/frontend/flow_graph_builder.h"
#include "vm/compiler/jit/compiler.h"
#include "vm/dart_entry.h"
#include "vm/longjump.h"
#include "vm/object_store.h"
#include "vm/regexp.h"
#include "vm/resolver.h"
#include "vm/runtime_entry.h"
#include "vm/stack_frame.h"
#include "vm/unicode.h"

#define Z zone()

// Debugging output macros. TAG() is called at the head of each interesting
// function and prints its name during execution if irregexp tracing is enabled.
#define TAG()                                                                  \
  if (FLAG_trace_irregexp) {                                                   \
    TAG_();                                                                    \
  }
#define TAG_()                                                                 \
  Print(PushArgument(Bind(new (Z) ConstantInstr(String::ZoneHandle(            \
      Z, String::Concat(String::Handle(String::New("TAG: ")),                  \
                        String::Handle(String::New(__FUNCTION__)),             \
                        Heap::kOld))))));

#define PRINT(arg)                                                             \
  if (FLAG_trace_irregexp) {                                                   \
    Print(arg);                                                                \
  }

namespace dart {

static const intptr_t kMinStackSize = 512;

/*
 * This assembler uses the following main local variables:
 * - stack_: A pointer to a growable list which we use as an all-purpose stack
 *           storing backtracking offsets, positions & stored register values.
 * - current_character_: Stores the currently loaded characters (possibly more
 *                       than one).
 * - current_position_: The current position within the string, stored as a
 *                      negative offset from the end of the string (i.e. the
 *                      position corresponding to str[0] is -str.length).
 *                      Note that current_position_ is *not* byte-based, unlike
 *                      original V8 code.
 *
 * Results are returned though an array of capture indices, stored at
 * matches_param_. A null array specifies a failure to match. The match indices
 * [start_inclusive, end_exclusive] for capture group i are stored at positions
 * matches_param_[i * 2] and matches_param_[i * 2 + 1], respectively. Match
 * indices of -1 denote non-matched groups. Note that we store these indices
 * as a negative offset from the end of the string in registers_array_
 * during processing, and convert them to standard indexes when copying them
 * to matches_param_ on successful match.
 */
IRRegExpMacroAssembler::IRRegExpMacroAssembler(
    intptr_t specialization_cid,
    intptr_t capture_count,
    const ParsedFunction* parsed_function,
    const ZoneGrowableArray<const ICData*>& ic_data_array,
    intptr_t osr_id,
    Zone* zone)
    : RegExpMacroAssembler(zone),
      thread_(Thread::Current()),
      specialization_cid_(specialization_cid),
      parsed_function_(parsed_function),
      ic_data_array_(ic_data_array),
      current_instruction_(NULL),
      stack_(NULL),
      stack_pointer_(NULL),
      current_character_(NULL),
      current_position_(NULL),
      string_param_(NULL),
      string_param_length_(NULL),
      start_index_param_(NULL),
      registers_count_(0),
      saved_registers_count_((capture_count + 1) * 2),
      stack_array_cell_(Array::ZoneHandle(zone, Array::New(1, Heap::kOld))),
      // The registers array is allocated at a fixed size after assembly.
      registers_array_(TypedData::ZoneHandle(zone, TypedData::null())),
      // B0 is taken by GraphEntry thus block ids must start at 1.
      block_id_(1) {
  switch (specialization_cid) {
    case kOneByteStringCid:
    case kExternalOneByteStringCid:
      mode_ = ASCII;
      break;
    case kTwoByteStringCid:
    case kExternalTwoByteStringCid:
      mode_ = UC16;
      break;
    default:
      UNREACHABLE();
  }

  InitializeLocals();

  // Allocate an initial stack backing of the minimum stack size. The stack
  // backing is indirectly referred to so we can reuse it on subsequent matches
  // even in the case where the backing has been enlarged and thus reallocated.
  stack_array_cell_.SetAt(
      0,
      TypedData::Handle(zone, TypedData::New(kTypedDataInt32ArrayCid,
                                             kMinStackSize / 4, Heap::kOld)));

  // Create and generate all preset blocks.
  entry_block_ = new (zone) GraphEntryInstr(*parsed_function_, osr_id);

  auto function_entry = new (zone) FunctionEntryInstr(
      entry_block_, block_id_.Alloc(), kInvalidTryIndex, GetNextDeoptId());
  entry_block_->set_normal_entry(function_entry);

  start_block_ = new (zone)
      JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex, GetNextDeoptId());
  success_block_ = new (zone)
      JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex, GetNextDeoptId());
  backtrack_block_ = new (zone)
      JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex, GetNextDeoptId());
  exit_block_ = new (zone)
      JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex, GetNextDeoptId());

  GenerateEntryBlock();
  GenerateSuccessBlock();
  GenerateExitBlock();

  blocks_.Add(entry_block_);
  blocks_.Add(entry_block_->normal_entry());
  blocks_.Add(start_block_);
  blocks_.Add(success_block_);
  blocks_.Add(backtrack_block_);
  blocks_.Add(exit_block_);

  // Begin emission at the start_block_.
  set_current_instruction(start_block_);
}

IRRegExpMacroAssembler::~IRRegExpMacroAssembler() {}

void IRRegExpMacroAssembler::InitializeLocals() {
  // All generated functions are expected to have a current-context variable.
  // This variable is unused in irregexp functions.
  parsed_function_->current_context_var()->set_index(
      VariableIndex(GetNextLocalIndex()));

  // Create local variables and parameters.
  stack_ = Local(Symbols::stack());
  stack_pointer_ = Local(Symbols::stack_pointer());
  registers_ = Local(Symbols::position_registers());
  current_character_ = Local(Symbols::current_character());
  current_position_ = Local(Symbols::current_position());
  string_param_length_ = Local(Symbols::string_param_length());
  capture_length_ = Local(Symbols::capture_length());
  match_start_index_ = Local(Symbols::match_start_index());
  capture_start_index_ = Local(Symbols::capture_start_index());
  match_end_index_ = Local(Symbols::match_end_index());
  char_in_capture_ = Local(Symbols::char_in_capture());
  char_in_match_ = Local(Symbols::char_in_match());
  index_temp_ = Local(Symbols::index_temp());
  result_ = Local(Symbols::result());

  string_param_ = Parameter(Symbols::string_param(),
                            RegExpMacroAssembler::kParamStringIndex);
  start_index_param_ = Parameter(Symbols::start_index_param(),
                                 RegExpMacroAssembler::kParamStartOffsetIndex);
}

void IRRegExpMacroAssembler::GenerateEntryBlock() {
  set_current_instruction(entry_block_->normal_entry());
  TAG();

  // Store string.length.
  PushArgumentInstr* string_push = PushLocal(string_param_);

  StoreLocal(string_param_length_,
             Bind(InstanceCall(InstanceCallDescriptor(String::ZoneHandle(
                                   Field::GetterSymbol(Symbols::Length()))),
                               string_push)));

  // Store (start_index - string.length) as the current position (since it's a
  // negative offset from the end of the string).
  PushArgumentInstr* start_index_push = PushLocal(start_index_param_);
  PushArgumentInstr* length_push = PushLocal(string_param_length_);

  StoreLocal(current_position_, Bind(Sub(start_index_push, length_push)));

  // Generate a local list variable to represent "registers" and
  // initialize capture registers (others remain garbage).
  StoreLocal(registers_, Bind(new (Z) ConstantInstr(registers_array_)));
  ClearRegisters(0, saved_registers_count_ - 1);

  // Generate a local list variable to represent the backtracking stack.
  PushArgumentInstr* stack_cell_push =
      PushArgument(Bind(new (Z) ConstantInstr(stack_array_cell_)));
  StoreLocal(stack_,
             Bind(InstanceCall(InstanceCallDescriptor::FromToken(Token::kINDEX),
                               stack_cell_push,
                               PushArgument(Bind(Uint64Constant(0))))));
  StoreLocal(stack_pointer_, Bind(Int64Constant(-1)));

  // Jump to the start block.
  current_instruction_->Goto(start_block_);
}

void IRRegExpMacroAssembler::GenerateBacktrackBlock() {
  set_current_instruction(backtrack_block_);
  TAG();
  CheckPreemption(/*is_backtrack=*/true);

  const intptr_t entries_count = entry_block_->indirect_entries().length();

  TypedData& offsets = TypedData::ZoneHandle(
      Z, TypedData::New(kTypedDataInt32ArrayCid, entries_count, Heap::kOld));

  PushArgumentInstr* block_offsets_push =
      PushArgument(Bind(new (Z) ConstantInstr(offsets)));
  PushArgumentInstr* block_id_push = PushArgument(Bind(PopStack()));

  Value* offset_value =
      Bind(InstanceCall(InstanceCallDescriptor::FromToken(Token::kINDEX),
                        block_offsets_push, block_id_push));

  backtrack_goto_ = new (Z) IndirectGotoInstr(&offsets, offset_value);
  CloseBlockWith(backtrack_goto_);

  // Add an edge from the "indirect" goto to each of the targets.
  for (intptr_t j = 0; j < entries_count; j++) {
    backtrack_goto_->AddSuccessor(
        TargetWithJoinGoto(entry_block_->indirect_entries().At(j)));
  }
}

void IRRegExpMacroAssembler::GenerateSuccessBlock() {
  set_current_instruction(success_block_);
  TAG();

  Value* type = Bind(new (Z) ConstantInstr(TypeArguments::ZoneHandle(
      Z, Isolate::Current()->object_store()->type_argument_int())));
  Value* length = Bind(Uint64Constant(saved_registers_count_));
  Value* array = Bind(new (Z) CreateArrayInstr(TokenPosition::kNoSource, type,
                                               length, GetNextDeoptId()));
  StoreLocal(result_, array);

  // Store captured offsets in the `matches` parameter.
  for (intptr_t i = 0; i < saved_registers_count_; i++) {
    PushArgumentInstr* matches_push = PushLocal(result_);
    PushArgumentInstr* index_push = PushArgument(Bind(Uint64Constant(i)));

    // Convert negative offsets from the end of the string to string indices.
    // TODO(zerny): use positive offsets from the get-go.
    PushArgumentInstr* offset_push = PushArgument(LoadRegister(i));
    PushArgumentInstr* len_push = PushLocal(string_param_length_);
    PushArgumentInstr* value_push =
        PushArgument(Bind(Add(offset_push, len_push)));

    Do(InstanceCall(InstanceCallDescriptor::FromToken(Token::kASSIGN_INDEX),
                    matches_push, index_push, value_push));
  }

  // Print the result if tracing.
  PRINT(PushLocal(result_));

  // Return true on success.
  AppendInstruction(new (Z) ReturnInstr(
      TokenPosition::kNoSource, Bind(LoadLocal(result_)), GetNextDeoptId()));
}

void IRRegExpMacroAssembler::GenerateExitBlock() {
  set_current_instruction(exit_block_);
  TAG();

  // Return false on failure.
  AppendInstruction(new (Z) ReturnInstr(
      TokenPosition::kNoSource, Bind(LoadLocal(result_)), GetNextDeoptId()));
}

void IRRegExpMacroAssembler::FinalizeRegistersArray() {
  ASSERT(registers_count_ >= saved_registers_count_);
  registers_array_ =
      TypedData::New(kTypedDataInt32ArrayCid, registers_count_, Heap::kOld);
}

#if defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_ARM)
// Disabling unaligned accesses forces the regexp engine to load characters one
// by one instead of up to 4 at once, along with the associated performance hit.
// TODO(zerny): Be less conservative about disabling unaligned accesses.
// For instance, ARMv6 supports unaligned accesses. Once it is enabled here,
// update LoadCodeUnitsInstr methods for the appropriate architectures.
static const bool kEnableUnalignedAccesses = false;
#else
static const bool kEnableUnalignedAccesses = true;
#endif
bool IRRegExpMacroAssembler::CanReadUnaligned() {
  return kEnableUnalignedAccesses && !slow_safe();
}

RawArray* IRRegExpMacroAssembler::Execute(const RegExp& regexp,
                                          const String& input,
                                          const Smi& start_offset,
                                          bool sticky,
                                          Zone* zone) {
  const intptr_t cid = input.GetClassId();
  const Function& fun = Function::Handle(regexp.function(cid, sticky));
  ASSERT(!fun.IsNull());
  // Create the argument list.
  const Array& args =
      Array::Handle(Array::New(RegExpMacroAssembler::kParamCount));
  args.SetAt(RegExpMacroAssembler::kParamRegExpIndex, regexp);
  args.SetAt(RegExpMacroAssembler::kParamStringIndex, input);
  args.SetAt(RegExpMacroAssembler::kParamStartOffsetIndex, start_offset);

  // And finally call the generated code.

  const Object& retval =
      Object::Handle(zone, DartEntry::InvokeFunction(fun, args));
  if (retval.IsUnwindError()) {
    Exceptions::PropagateError(Error::Cast(retval));
  }
  if (retval.IsError()) {
    const Error& error = Error::Cast(retval);
    OS::PrintErr("%s\n", error.ToErrorCString());
    // Should never happen.
    UNREACHABLE();
  }

  if (retval.IsNull()) {
    return Array::null();
  }

  ASSERT(retval.IsArray());
  return Array::Cast(retval).raw();
}

LocalVariable* IRRegExpMacroAssembler::Parameter(const String& name,
                                                 intptr_t index) const {
  LocalVariable* local =
      new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
                            name, Object::dynamic_type());

  intptr_t param_frame_index = kParamCount - index;
  local->set_index(VariableIndex(param_frame_index));

  return local;
}

LocalVariable* IRRegExpMacroAssembler::Local(const String& name) {
  LocalVariable* local =
      new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
                            name, Object::dynamic_type());
  local->set_index(VariableIndex(GetNextLocalIndex()));

  return local;
}

ConstantInstr* IRRegExpMacroAssembler::Int64Constant(int64_t value) const {
  return new (Z)
      ConstantInstr(Integer::ZoneHandle(Z, Integer::New(value, Heap::kOld)));
}

ConstantInstr* IRRegExpMacroAssembler::Uint64Constant(uint64_t value) const {
  ASSERT(value < static_cast<uint64_t>(kMaxInt64));
  return Int64Constant(static_cast<int64_t>(value));
}

ConstantInstr* IRRegExpMacroAssembler::BoolConstant(bool value) const {
  return new (Z) ConstantInstr(value ? Bool::True() : Bool::False());
}

ConstantInstr* IRRegExpMacroAssembler::StringConstant(const char* value) const {
  return new (Z)
      ConstantInstr(String::ZoneHandle(Z, String::New(value, Heap::kOld)));
}

ConstantInstr* IRRegExpMacroAssembler::WordCharacterMapConstant() const {
  const Library& lib = Library::Handle(Z, Library::CoreLibrary());
  const Class& regexp_class =
      Class::Handle(Z, lib.LookupClassAllowPrivate(Symbols::_RegExp()));
  const Field& word_character_field = Field::ZoneHandle(
      Z,
      regexp_class.LookupStaticFieldAllowPrivate(Symbols::_wordCharacterMap()));
  ASSERT(!word_character_field.IsNull());

  DEBUG_ASSERT(Thread::Current()->TopErrorHandlerIsSetJump());
  if (word_character_field.IsUninitialized()) {
    ASSERT(!Compiler::IsBackgroundCompilation());
    const Error& error =
        Error::Handle(Z, word_character_field.EvaluateInitializer());
    if (!error.IsNull()) {
      Report::LongJump(error);
    }
  }
  ASSERT(!word_character_field.IsUninitialized());

  return new (Z) ConstantInstr(
      Instance::ZoneHandle(Z, word_character_field.StaticValue()));
}

ComparisonInstr* IRRegExpMacroAssembler::Comparison(ComparisonKind kind,
                                                    PushArgumentInstr* lhs,
                                                    PushArgumentInstr* rhs) {
  Token::Kind strict_comparison = Token::kEQ_STRICT;
  Token::Kind intermediate_operator = Token::kILLEGAL;
  switch (kind) {
    case kEQ:
      intermediate_operator = Token::kEQ;
      break;
    case kNE:
      intermediate_operator = Token::kEQ;
      strict_comparison = Token::kNE_STRICT;
      break;
    case kLT:
      intermediate_operator = Token::kLT;
      break;
    case kGT:
      intermediate_operator = Token::kGT;
      break;
    case kLTE:
      intermediate_operator = Token::kLTE;
      break;
    case kGTE:
      intermediate_operator = Token::kGTE;
      break;
    default:
      UNREACHABLE();
  }

  ASSERT(intermediate_operator != Token::kILLEGAL);

  Value* lhs_value = Bind(InstanceCall(
      InstanceCallDescriptor::FromToken(intermediate_operator), lhs, rhs));
  Value* rhs_value = Bind(BoolConstant(true));

  return new (Z)
      StrictCompareInstr(TokenPosition::kNoSource, strict_comparison, lhs_value,
                         rhs_value, true, GetNextDeoptId());
}

ComparisonInstr* IRRegExpMacroAssembler::Comparison(ComparisonKind kind,
                                                    Definition* lhs,
                                                    Definition* rhs) {
  PushArgumentInstr* lhs_push = PushArgument(Bind(lhs));
  PushArgumentInstr* rhs_push = PushArgument(Bind(rhs));
  return Comparison(kind, lhs_push, rhs_push);
}

StaticCallInstr* IRRegExpMacroAssembler::StaticCall(
    const Function& function,
    ICData::RebindRule rebind_rule) const {
  ZoneGrowableArray<PushArgumentInstr*>* arguments =
      new (Z) ZoneGrowableArray<PushArgumentInstr*>(0);
  return StaticCall(function, arguments, rebind_rule);
}

StaticCallInstr* IRRegExpMacroAssembler::StaticCall(
    const Function& function,
    PushArgumentInstr* arg1,
    ICData::RebindRule rebind_rule) const {
  ZoneGrowableArray<PushArgumentInstr*>* arguments =
      new (Z) ZoneGrowableArray<PushArgumentInstr*>(1);
  arguments->Add(arg1);

  return StaticCall(function, arguments, rebind_rule);
}

StaticCallInstr* IRRegExpMacroAssembler::StaticCall(
    const Function& function,
    PushArgumentInstr* arg1,
    PushArgumentInstr* arg2,
    ICData::RebindRule rebind_rule) const {
  ZoneGrowableArray<PushArgumentInstr*>* arguments =
      new (Z) ZoneGrowableArray<PushArgumentInstr*>(2);
  arguments->Add(arg1);
  arguments->Add(arg2);

  return StaticCall(function, arguments, rebind_rule);
}

StaticCallInstr* IRRegExpMacroAssembler::StaticCall(
    const Function& function,
    ZoneGrowableArray<PushArgumentInstr*>* arguments,
    ICData::RebindRule rebind_rule) const {
  const intptr_t kTypeArgsLen = 0;
  return new (Z) StaticCallInstr(TokenPosition::kNoSource, function,
                                 kTypeArgsLen, Object::null_array(), arguments,
                                 ic_data_array_, GetNextDeoptId(), rebind_rule);
}

InstanceCallInstr* IRRegExpMacroAssembler::InstanceCall(
    const InstanceCallDescriptor& desc,
    PushArgumentInstr* arg1) const {
  ZoneGrowableArray<PushArgumentInstr*>* arguments =
      new (Z) ZoneGrowableArray<PushArgumentInstr*>(1);
  arguments->Add(arg1);

  return InstanceCall(desc, arguments);
}

InstanceCallInstr* IRRegExpMacroAssembler::InstanceCall(
    const InstanceCallDescriptor& desc,
    PushArgumentInstr* arg1,
    PushArgumentInstr* arg2) const {
  ZoneGrowableArray<PushArgumentInstr*>* arguments =
      new (Z) ZoneGrowableArray<PushArgumentInstr*>(2);
  arguments->Add(arg1);
  arguments->Add(arg2);

  return InstanceCall(desc, arguments);
}

InstanceCallInstr* IRRegExpMacroAssembler::InstanceCall(
    const InstanceCallDescriptor& desc,
    PushArgumentInstr* arg1,
    PushArgumentInstr* arg2,
    PushArgumentInstr* arg3) const {
  ZoneGrowableArray<PushArgumentInstr*>* arguments =
      new (Z) ZoneGrowableArray<PushArgumentInstr*>(3);
  arguments->Add(arg1);
  arguments->Add(arg2);
  arguments->Add(arg3);

  return InstanceCall(desc, arguments);
}

InstanceCallInstr* IRRegExpMacroAssembler::InstanceCall(
    const InstanceCallDescriptor& desc,
    ZoneGrowableArray<PushArgumentInstr*>* arguments) const {
  const intptr_t kTypeArgsLen = 0;
  return new (Z) InstanceCallInstr(
      TokenPosition::kNoSource, desc.name, desc.token_kind, arguments,
      kTypeArgsLen, Object::null_array(), desc.checked_argument_count,
      ic_data_array_, GetNextDeoptId());
}

LoadLocalInstr* IRRegExpMacroAssembler::LoadLocal(LocalVariable* local) const {
  return new (Z) LoadLocalInstr(*local, TokenPosition::kNoSource);
}

void IRRegExpMacroAssembler::StoreLocal(LocalVariable* local, Value* value) {
  Do(new (Z) StoreLocalInstr(*local, value, TokenPosition::kNoSource));
}

void IRRegExpMacroAssembler::set_current_instruction(Instruction* instruction) {
  current_instruction_ = instruction;
}

Value* IRRegExpMacroAssembler::Bind(Definition* definition) {
  AppendInstruction(definition);
  definition->set_temp_index(temp_id_.Alloc());

  return new (Z) Value(definition);
}

void IRRegExpMacroAssembler::Do(Definition* definition) {
  AppendInstruction(definition);
}

Value* IRRegExpMacroAssembler::BindLoadLocal(const LocalVariable& local) {
  if (local.IsConst()) {
    return Bind(new (Z) ConstantInstr(*local.ConstValue()));
  }
  ASSERT(!local.is_captured());
  return Bind(new (Z) LoadLocalInstr(local, TokenPosition::kNoSource));
}

// In some cases, the V8 irregexp engine generates unreachable code by emitting
// a jmp not followed by a bind. We cannot do the same, since it is impossible
// to append to a block following a jmp. In such cases, assume that we are doing
// the correct thing, but output a warning when tracing.
#define HANDLE_DEAD_CODE_EMISSION()                                            \
  if (current_instruction_ == NULL) {                                          \
    if (FLAG_trace_irregexp) {                                                 \
      OS::PrintErr(                                                            \
          "WARNING: Attempting to append to a closed assembler. "              \
          "This could be either a bug or generation of dead code "             \
          "inherited from V8.\n");                                             \
    }                                                                          \
    BlockLabel dummy;                                                          \
    BindBlock(&dummy);                                                         \
  }

void IRRegExpMacroAssembler::AppendInstruction(Instruction* instruction) {
  HANDLE_DEAD_CODE_EMISSION();

  ASSERT(current_instruction_ != NULL);
  ASSERT(current_instruction_->next() == NULL);

  temp_id_.Dealloc(instruction->InputCount());
  arg_id_.Dealloc(instruction->ArgumentCount());

  current_instruction_->LinkTo(instruction);
  set_current_instruction(instruction);
}

void IRRegExpMacroAssembler::CloseBlockWith(Instruction* instruction) {
  HANDLE_DEAD_CODE_EMISSION();

  ASSERT(current_instruction_ != NULL);
  ASSERT(current_instruction_->next() == NULL);

  temp_id_.Dealloc(instruction->InputCount());
  arg_id_.Dealloc(instruction->ArgumentCount());

  current_instruction_->LinkTo(instruction);
  set_current_instruction(NULL);
}

void IRRegExpMacroAssembler::GoTo(BlockLabel* to) {
  if (to == NULL) {
    Backtrack();
  } else {
    to->SetLinked();
    GoTo(to->block());
  }
}

// Closes the current block with a goto, and unsets current_instruction_.
// BindBlock() must be called before emission can continue.
void IRRegExpMacroAssembler::GoTo(JoinEntryInstr* to) {
  HANDLE_DEAD_CODE_EMISSION();

  ASSERT(current_instruction_ != NULL);
  ASSERT(current_instruction_->next() == NULL);
  current_instruction_->Goto(to);
  set_current_instruction(NULL);
}

PushArgumentInstr* IRRegExpMacroAssembler::PushArgument(Value* value) {
  arg_id_.Alloc();
  PushArgumentInstr* push = new (Z) PushArgumentInstr(value);
  // Do *not* use Do() for push argument instructions.
  AppendInstruction(push);
  return push;
}

PushArgumentInstr* IRRegExpMacroAssembler::PushLocal(LocalVariable* local) {
  return PushArgument(Bind(LoadLocal(local)));
}

void IRRegExpMacroAssembler::Print(const char* str) {
  Print(PushArgument(Bind(new (Z) ConstantInstr(
      String::ZoneHandle(Z, String::New(str, Heap::kOld))))));
}

void IRRegExpMacroAssembler::Print(PushArgumentInstr* argument) {
  const Library& lib = Library::Handle(Library::CoreLibrary());
  const Function& print_fn =
      Function::ZoneHandle(Z, lib.LookupFunctionAllowPrivate(Symbols::print()));
  Do(StaticCall(print_fn, argument, ICData::kStatic));
}

void IRRegExpMacroAssembler::PrintBlocks() {
  for (intptr_t i = 0; i < blocks_.length(); i++) {
    FlowGraphPrinter::PrintBlock(blocks_[i], false);
  }
}

intptr_t IRRegExpMacroAssembler::stack_limit_slack() {
  return 32;
}

void IRRegExpMacroAssembler::AdvanceCurrentPosition(intptr_t by) {
  TAG();
  if (by != 0) {
    PushArgumentInstr* cur_pos_push = PushLocal(current_position_);
    PushArgumentInstr* by_push = PushArgument(Bind(Int64Constant(by)));

    Value* new_pos_value = Bind(Add(cur_pos_push, by_push));
    StoreLocal(current_position_, new_pos_value);
  }
}

void IRRegExpMacroAssembler::AdvanceRegister(intptr_t reg, intptr_t by) {
  TAG();
  ASSERT(reg >= 0);
  ASSERT(reg < registers_count_);

  if (by != 0) {
    PushArgumentInstr* registers_push = PushLocal(registers_);
    PushArgumentInstr* index_push = PushRegisterIndex(reg);
    PushArgumentInstr* reg_push = PushArgument(LoadRegister(reg));
    PushArgumentInstr* by_push = PushArgument(Bind(Int64Constant(by)));
    PushArgumentInstr* value_push = PushArgument(Bind(Add(reg_push, by_push)));
    StoreRegister(registers_push, index_push, value_push);
  }
}

void IRRegExpMacroAssembler::Backtrack() {
  TAG();
  GoTo(backtrack_block_);
}

// A BindBlock is analogous to assigning a label to a basic block.
// If the BlockLabel does not yet contain a block, it is created.
// If there is a current instruction, append a goto to the bound block.
void IRRegExpMacroAssembler::BindBlock(BlockLabel* label) {
  ASSERT(!label->IsBound());
  ASSERT(label->block()->next() == NULL);

  label->SetBound(block_id_.Alloc());
  blocks_.Add(label->block());

  if (current_instruction_ != NULL) {
    GoTo(label);
  }
  set_current_instruction(label->block());

  // Print the id of the current block if tracing.
  PRINT(PushArgument(Bind(Uint64Constant(label->block()->block_id()))));
}

intptr_t IRRegExpMacroAssembler::GetNextLocalIndex() {
  intptr_t id = local_id_.Alloc();
  return -id;
}

Value* IRRegExpMacroAssembler::LoadRegister(intptr_t index) {
  PushArgumentInstr* registers_push = PushLocal(registers_);
  PushArgumentInstr* index_push = PushRegisterIndex(index);
  return Bind(InstanceCall(InstanceCallDescriptor::FromToken(Token::kINDEX),
                           registers_push, index_push));
}

void IRRegExpMacroAssembler::StoreRegister(intptr_t index, intptr_t value) {
  PushArgumentInstr* registers_push = PushLocal(registers_);
  PushArgumentInstr* index_push = PushRegisterIndex(index);
  PushArgumentInstr* value_push = PushArgument(Bind(Uint64Constant(value)));
  StoreRegister(registers_push, index_push, value_push);
}

void IRRegExpMacroAssembler::StoreRegister(PushArgumentInstr* registers,
                                           PushArgumentInstr* index,
                                           PushArgumentInstr* value) {
  TAG();
  Do(InstanceCall(InstanceCallDescriptor::FromToken(Token::kASSIGN_INDEX),
                  registers, index, value));
}

PushArgumentInstr* IRRegExpMacroAssembler::PushRegisterIndex(intptr_t index) {
  if (registers_count_ <= index) {
    registers_count_ = index + 1;
  }
  return PushArgument(Bind(Uint64Constant(index)));
}

void IRRegExpMacroAssembler::CheckCharacter(uint32_t c, BlockLabel* on_equal) {
  TAG();
  Definition* cur_char_def = LoadLocal(current_character_);
  Definition* char_def = Uint64Constant(c);

  BranchOrBacktrack(Comparison(kEQ, cur_char_def, char_def), on_equal);
}

void IRRegExpMacroAssembler::CheckCharacterGT(uint16_t limit,
                                              BlockLabel* on_greater) {
  TAG();
  BranchOrBacktrack(
      Comparison(kGT, LoadLocal(current_character_), Uint64Constant(limit)),
      on_greater);
}

void IRRegExpMacroAssembler::CheckAtStart(BlockLabel* on_at_start) {
  TAG();

  // Are we at the start of the input, i.e. is (offset == string_length * -1)?
  Definition* neg_len_def =
      InstanceCall(InstanceCallDescriptor::FromToken(Token::kNEGATE),
                   PushLocal(string_param_length_));
  Definition* offset_def = LoadLocal(current_position_);
  BranchOrBacktrack(Comparison(kEQ, neg_len_def, offset_def), on_at_start);
}

// cp_offset => offset from the current (character) pointer
// This offset may be negative due to traversing backwards during lookbehind.
void IRRegExpMacroAssembler::CheckNotAtStart(intptr_t cp_offset,
                                             BlockLabel* on_not_at_start) {
  TAG();

  // Are we at the start of the input, i.e. is (offset == string_length * -1)?
  auto offset_def =
      PushArgument(Bind(Add(PushLocal(current_position_),
                            PushArgument(Bind(Int64Constant(cp_offset))))));
  auto neg_len_def = PushArgument(
      Bind(InstanceCall(InstanceCallDescriptor::FromToken(Token::kNEGATE),
                        PushLocal(string_param_length_))));
  BranchOrBacktrack(Comparison(kNE, neg_len_def, offset_def), on_not_at_start);
}

void IRRegExpMacroAssembler::CheckCharacterLT(uint16_t limit,
                                              BlockLabel* on_less) {
  TAG();
  BranchOrBacktrack(
      Comparison(kLT, LoadLocal(current_character_), Uint64Constant(limit)),
      on_less);
}

void IRRegExpMacroAssembler::CheckGreedyLoop(BlockLabel* on_equal) {
  TAG();

  BlockLabel fallthrough;

  Definition* head = PeekStack();
  Definition* cur_pos_def = LoadLocal(current_position_);
  BranchOrBacktrack(Comparison(kNE, head, cur_pos_def), &fallthrough);

  // Pop, throwing away the value.
  Do(PopStack());

  BranchOrBacktrack(NULL, on_equal);

  BindBlock(&fallthrough);
}

void IRRegExpMacroAssembler::CheckNotBackReferenceIgnoreCase(
    intptr_t start_reg,
    bool read_backward,
    BlockLabel* on_no_match) {
  TAG();
  ASSERT(start_reg + 1 <= registers_count_);

  BlockLabel fallthrough;

  PushArgumentInstr* end_push = PushArgument(LoadRegister(start_reg + 1));
  PushArgumentInstr* start_push = PushArgument(LoadRegister(start_reg));
  StoreLocal(capture_length_, Bind(Sub(end_push, start_push)));

  // The length of a capture should not be negative. This can only happen
  // if the end of the capture is unrecorded, or at a point earlier than
  // the start of the capture.
  // BranchOrBacktrack(less, on_no_match);

  BranchOrBacktrack(
      Comparison(kLT, LoadLocal(capture_length_), Uint64Constant(0)),
      on_no_match);

  // If length is zero, either the capture is empty or it is completely
  // uncaptured. In either case succeed immediately.
  BranchOrBacktrack(
      Comparison(kEQ, LoadLocal(capture_length_), Uint64Constant(0)),
      &fallthrough);

  PushArgumentInstr* pos_push = nullptr;
  PushArgumentInstr* len_push = nullptr;

  if (!read_backward) {
    // Check that there are sufficient characters left in the input.
    pos_push = PushLocal(current_position_);
    len_push = PushLocal(capture_length_);
    BranchOrBacktrack(
        Comparison(kGT,
                   InstanceCall(InstanceCallDescriptor::FromToken(Token::kADD),
                                pos_push, len_push),
                   Uint64Constant(0)),
        on_no_match);
  }

  pos_push = PushLocal(current_position_);
  len_push = PushLocal(string_param_length_);
  StoreLocal(match_start_index_, Bind(Add(pos_push, len_push)));

  if (read_backward) {
    // First check that there are enough characters before this point in
    // the string that we can match the backreference.
    BranchOrBacktrack(Comparison(kLT, LoadLocal(match_start_index_),
                                 LoadLocal(capture_length_)),
                      on_no_match);

    // The string to check is before the current position, not at it.
    pos_push = PushLocal(match_start_index_);
    len_push = PushLocal(capture_length_);
    StoreLocal(match_start_index_, Bind(Sub(pos_push, len_push)));
  }

  pos_push = PushArgument(LoadRegister(start_reg));
  len_push = PushLocal(string_param_length_);
  StoreLocal(capture_start_index_, Bind(Add(pos_push, len_push)));

  pos_push = PushLocal(match_start_index_);
  len_push = PushLocal(capture_length_);
  StoreLocal(match_end_index_, Bind(Add(pos_push, len_push)));

  BlockLabel success;
  if (mode_ == ASCII) {
    BlockLabel loop_increment;
    BlockLabel loop;
    BindBlock(&loop);

    StoreLocal(char_in_capture_, CharacterAt(capture_start_index_));
    StoreLocal(char_in_match_, CharacterAt(match_start_index_));

    BranchOrBacktrack(
        Comparison(kEQ, LoadLocal(char_in_capture_), LoadLocal(char_in_match_)),
        &loop_increment);

    // Mismatch, try case-insensitive match (converting letters to lower-case).
    PushArgumentInstr* match_char_push = PushLocal(char_in_match_);
    PushArgumentInstr* mask_push = PushArgument(Bind(Uint64Constant(0x20)));
    StoreLocal(
        char_in_match_,
        Bind(InstanceCall(InstanceCallDescriptor::FromToken(Token::kBIT_OR),
                          match_char_push, mask_push)));

    BlockLabel convert_capture;
    BlockLabel on_not_in_range;
    BranchOrBacktrack(
        Comparison(kLT, LoadLocal(char_in_match_), Uint64Constant('a')),
        &on_not_in_range);
    BranchOrBacktrack(
        Comparison(kGT, LoadLocal(char_in_match_), Uint64Constant('z')),
        &on_not_in_range);
    GoTo(&convert_capture);
    BindBlock(&on_not_in_range);

    // Latin-1: Check for values in range [224,254] but not 247.
    BranchOrBacktrack(
        Comparison(kLT, LoadLocal(char_in_match_), Uint64Constant(224)),
        on_no_match);
    BranchOrBacktrack(
        Comparison(kGT, LoadLocal(char_in_match_), Uint64Constant(254)),
        on_no_match);

    BranchOrBacktrack(
        Comparison(kEQ, LoadLocal(char_in_match_), Uint64Constant(247)),
        on_no_match);

    // Also convert capture character.
    BindBlock(&convert_capture);

    PushArgumentInstr* capture_char_push = PushLocal(char_in_capture_);
    mask_push = PushArgument(Bind(Uint64Constant(0x20)));
    StoreLocal(
        char_in_capture_,
        Bind(InstanceCall(InstanceCallDescriptor::FromToken(Token::kBIT_OR),
                          capture_char_push, mask_push)));

    BranchOrBacktrack(
        Comparison(kNE, LoadLocal(char_in_match_), LoadLocal(char_in_capture_)),
        on_no_match);

    BindBlock(&loop_increment);

    // Increment indexes into capture and match strings.
    PushArgumentInstr* index_push = PushLocal(capture_start_index_);
    PushArgumentInstr* inc_push = PushArgument(Bind(Uint64Constant(1)));
    StoreLocal(capture_start_index_, Bind(Add(index_push, inc_push)));

    index_push = PushLocal(match_start_index_);
    inc_push = PushArgument(Bind(Uint64Constant(1)));
    StoreLocal(match_start_index_, Bind(Add(index_push, inc_push)));

    // Compare to end of match, and loop if not done.
    BranchOrBacktrack(Comparison(kLT, LoadLocal(match_start_index_),
                                 LoadLocal(match_end_index_)),
                      &loop);
  } else {
    ASSERT(mode_ == UC16);

    Value* string_value = Bind(LoadLocal(string_param_));
    Value* lhs_index_value = Bind(LoadLocal(match_start_index_));
    Value* rhs_index_value = Bind(LoadLocal(capture_start_index_));
    Value* length_value = Bind(LoadLocal(capture_length_));

    Definition* is_match_def = new (Z) CaseInsensitiveCompareUC16Instr(
        string_value, lhs_index_value, rhs_index_value, length_value,
        specialization_cid_);

    BranchOrBacktrack(Comparison(kNE, is_match_def, BoolConstant(true)),
                      on_no_match);
  }

  BindBlock(&success);

  if (read_backward) {
    // Move current character position to start of match.
    pos_push = PushLocal(current_position_);
    len_push = PushLocal(capture_length_);
    StoreLocal(current_position_, Bind(Sub(pos_push, len_push)));
  } else {
    // Move current character position to position after match.
    PushArgumentInstr* match_end_push = PushLocal(match_end_index_);
    len_push = PushLocal(string_param_length_);
    StoreLocal(current_position_, Bind(Sub(match_end_push, len_push)));
  }

  BindBlock(&fallthrough);
}

void IRRegExpMacroAssembler::CheckNotBackReference(intptr_t start_reg,
                                                   bool read_backward,
                                                   BlockLabel* on_no_match) {
  TAG();
  ASSERT(start_reg + 1 <= registers_count_);

  BlockLabel fallthrough;
  BlockLabel success;

  // Find length of back-referenced capture.
  PushArgumentInstr* end_push = PushArgument(LoadRegister(start_reg + 1));
  PushArgumentInstr* start_push = PushArgument(LoadRegister(start_reg));
  StoreLocal(capture_length_, Bind(Sub(end_push, start_push)));

  // Fail on partial or illegal capture (start of capture after end of capture).
  BranchOrBacktrack(
      Comparison(kLT, LoadLocal(capture_length_), Uint64Constant(0)),
      on_no_match);

  // Succeed on empty capture (including no capture)
  BranchOrBacktrack(
      Comparison(kEQ, LoadLocal(capture_length_), Uint64Constant(0)),
      &fallthrough);

  PushArgumentInstr* pos_push = nullptr;
  PushArgumentInstr* len_push = nullptr;

  if (!read_backward) {
    // Check that there are sufficient characters left in the input.
    pos_push = PushLocal(current_position_);
    len_push = PushLocal(capture_length_);
    BranchOrBacktrack(
        Comparison(kGT,
                   InstanceCall(InstanceCallDescriptor::FromToken(Token::kADD),
                                pos_push, len_push),
                   Uint64Constant(0)),
        on_no_match);
  }

  // Compute pointers to match string and capture string.
  pos_push = PushLocal(current_position_);
  len_push = PushLocal(string_param_length_);
  StoreLocal(match_start_index_, Bind(Add(pos_push, len_push)));

  if (read_backward) {
    // First check that there are enough characters before this point in
    // the string that we can match the backreference.
    BranchOrBacktrack(Comparison(kLT, LoadLocal(match_start_index_),
                                 LoadLocal(capture_length_)),
                      on_no_match);

    // The string to check is before the current position, not at it.
    pos_push = PushLocal(match_start_index_);
    len_push = PushLocal(capture_length_);
    StoreLocal(match_start_index_, Bind(Sub(pos_push, len_push)));
  }

  pos_push = PushArgument(LoadRegister(start_reg));
  len_push = PushLocal(string_param_length_);
  StoreLocal(capture_start_index_, Bind(Add(pos_push, len_push)));

  pos_push = PushLocal(match_start_index_);
  len_push = PushLocal(capture_length_);
  StoreLocal(match_end_index_, Bind(Add(pos_push, len_push)));

  BlockLabel loop;
  BindBlock(&loop);

  StoreLocal(char_in_capture_, CharacterAt(capture_start_index_));
  StoreLocal(char_in_match_, CharacterAt(match_start_index_));

  BranchOrBacktrack(
      Comparison(kNE, LoadLocal(char_in_capture_), LoadLocal(char_in_match_)),
      on_no_match);

  // Increment indexes into capture and match strings.
  PushArgumentInstr* index_push = PushLocal(capture_start_index_);
  PushArgumentInstr* inc_push = PushArgument(Bind(Uint64Constant(1)));
  StoreLocal(capture_start_index_, Bind(Add(index_push, inc_push)));

  index_push = PushLocal(match_start_index_);
  inc_push = PushArgument(Bind(Uint64Constant(1)));
  StoreLocal(match_start_index_, Bind(Add(index_push, inc_push)));

  // Check if we have reached end of match area.
  BranchOrBacktrack(Comparison(kLT, LoadLocal(match_start_index_),
                               LoadLocal(match_end_index_)),
                    &loop);

  BindBlock(&success);

  if (read_backward) {
    // Move current character position to start of match.
    pos_push = PushLocal(current_position_);
    len_push = PushLocal(capture_length_);
    StoreLocal(current_position_, Bind(Sub(pos_push, len_push)));
  } else {
    // Move current character position to position after match.
    PushArgumentInstr* match_end_push = PushLocal(match_end_index_);
    len_push = PushLocal(string_param_length_);
    StoreLocal(current_position_, Bind(Sub(match_end_push, len_push)));
  }

  BindBlock(&fallthrough);
}

void IRRegExpMacroAssembler::CheckNotCharacter(uint32_t c,
                                               BlockLabel* on_not_equal) {
  TAG();
  BranchOrBacktrack(
      Comparison(kNE, LoadLocal(current_character_), Uint64Constant(c)),
      on_not_equal);
}

void IRRegExpMacroAssembler::CheckCharacterAfterAnd(uint32_t c,
                                                    uint32_t mask,
                                                    BlockLabel* on_equal) {
  TAG();

  Definition* actual_def = LoadLocal(current_character_);
  Definition* expected_def = Uint64Constant(c);

  PushArgumentInstr* actual_push = PushArgument(Bind(actual_def));
  PushArgumentInstr* mask_push = PushArgument(Bind(Uint64Constant(mask)));
  actual_def = InstanceCall(InstanceCallDescriptor::FromToken(Token::kBIT_AND),
                            actual_push, mask_push);

  BranchOrBacktrack(Comparison(kEQ, actual_def, expected_def), on_equal);
}

void IRRegExpMacroAssembler::CheckNotCharacterAfterAnd(
    uint32_t c,
    uint32_t mask,
    BlockLabel* on_not_equal) {
  TAG();

  Definition* actual_def = LoadLocal(current_character_);
  Definition* expected_def = Uint64Constant(c);

  PushArgumentInstr* actual_push = PushArgument(Bind(actual_def));
  PushArgumentInstr* mask_push = PushArgument(Bind(Uint64Constant(mask)));
  actual_def = InstanceCall(InstanceCallDescriptor::FromToken(Token::kBIT_AND),
                            actual_push, mask_push);

  BranchOrBacktrack(Comparison(kNE, actual_def, expected_def), on_not_equal);
}

void IRRegExpMacroAssembler::CheckNotCharacterAfterMinusAnd(
    uint16_t c,
    uint16_t minus,
    uint16_t mask,
    BlockLabel* on_not_equal) {
  TAG();
  ASSERT(minus < Utf16::kMaxCodeUnit);  // NOLINT

  Definition* actual_def = LoadLocal(current_character_);
  Definition* expected_def = Uint64Constant(c);

  PushArgumentInstr* actual_push = PushArgument(Bind(actual_def));
  PushArgumentInstr* minus_push = PushArgument(Bind(Uint64Constant(minus)));

  actual_push = PushArgument(Bind(Sub(actual_push, minus_push)));
  PushArgumentInstr* mask_push = PushArgument(Bind(Uint64Constant(mask)));
  actual_def = InstanceCall(InstanceCallDescriptor::FromToken(Token::kBIT_AND),
                            actual_push, mask_push);

  BranchOrBacktrack(Comparison(kNE, actual_def, expected_def), on_not_equal);
}

void IRRegExpMacroAssembler::CheckCharacterInRange(uint16_t from,
                                                   uint16_t to,
                                                   BlockLabel* on_in_range) {
  TAG();
  ASSERT(from <= to);

  // TODO(zerny): All range comparisons could be done cheaper with unsigned
  // compares. This pattern repeats in various places.

  BlockLabel on_not_in_range;
  BranchOrBacktrack(
      Comparison(kLT, LoadLocal(current_character_), Uint64Constant(from)),
      &on_not_in_range);
  BranchOrBacktrack(
      Comparison(kGT, LoadLocal(current_character_), Uint64Constant(to)),
      &on_not_in_range);
  BranchOrBacktrack(NULL, on_in_range);

  BindBlock(&on_not_in_range);
}

void IRRegExpMacroAssembler::CheckCharacterNotInRange(
    uint16_t from,
    uint16_t to,
    BlockLabel* on_not_in_range) {
  TAG();
  ASSERT(from <= to);

  BranchOrBacktrack(
      Comparison(kLT, LoadLocal(current_character_), Uint64Constant(from)),
      on_not_in_range);

  BranchOrBacktrack(
      Comparison(kGT, LoadLocal(current_character_), Uint64Constant(to)),
      on_not_in_range);
}

void IRRegExpMacroAssembler::CheckBitInTable(const TypedData& table,
                                             BlockLabel* on_bit_set) {
  TAG();

  PushArgumentInstr* table_push =
      PushArgument(Bind(new (Z) ConstantInstr(table)));
  PushArgumentInstr* index_push = PushLocal(current_character_);

  if (mode_ != ASCII || kTableMask != Symbols::kMaxOneCharCodeSymbol) {
    PushArgumentInstr* mask_push =
        PushArgument(Bind(Uint64Constant(kTableSize - 1)));
    index_push = PushArgument(
        Bind(InstanceCall(InstanceCallDescriptor::FromToken(Token::kBIT_AND),
                          index_push, mask_push)));
  }

  Definition* byte_def = InstanceCall(
      InstanceCallDescriptor::FromToken(Token::kINDEX), table_push, index_push);
  Definition* zero_def = Int64Constant(0);

  BranchOrBacktrack(Comparison(kNE, byte_def, zero_def), on_bit_set);
}

bool IRRegExpMacroAssembler::CheckSpecialCharacterClass(
    uint16_t type,
    BlockLabel* on_no_match) {
  TAG();

  // Range checks (c in min..max) are generally implemented by an unsigned
  // (c - min) <= (max - min) check
  switch (type) {
    case 's':
      // Match space-characters
      if (mode_ == ASCII) {
        // One byte space characters are '\t'..'\r', ' ' and \u00a0.
        BlockLabel success;
        // Space (' ').
        BranchOrBacktrack(
            Comparison(kEQ, LoadLocal(current_character_), Uint64Constant(' ')),
            &success);
        // Check range 0x09..0x0d.
        CheckCharacterInRange('\t', '\r', &success);
        // \u00a0 (NBSP).
        BranchOrBacktrack(Comparison(kNE, LoadLocal(current_character_),
                                     Uint64Constant(0x00a0)),
                          on_no_match);
        BindBlock(&success);
        return true;
      }
      return false;
    case 'S':
      // The emitted code for generic character classes is good enough.
      return false;
    case 'd':
      // Match ASCII digits ('0'..'9')
      CheckCharacterNotInRange('0', '9', on_no_match);
      return true;
    case 'D':
      // Match non ASCII-digits
      CheckCharacterInRange('0', '9', on_no_match);
      return true;
    case '.': {
      // Match non-newlines (not 0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029)
      BranchOrBacktrack(
          Comparison(kEQ, LoadLocal(current_character_), Uint64Constant('\n')),
          on_no_match);
      BranchOrBacktrack(
          Comparison(kEQ, LoadLocal(current_character_), Uint64Constant('\r')),
          on_no_match);
      if (mode_ == UC16) {
        BranchOrBacktrack(Comparison(kEQ, LoadLocal(current_character_),
                                     Uint64Constant(0x2028)),
                          on_no_match);
        BranchOrBacktrack(Comparison(kEQ, LoadLocal(current_character_),
                                     Uint64Constant(0x2029)),
                          on_no_match);
      }
      return true;
    }
    case 'w': {
      if (mode_ != ASCII) {
        // Table is 128 entries, so all ASCII characters can be tested.
        BranchOrBacktrack(
            Comparison(kGT, LoadLocal(current_character_), Uint64Constant('z')),
            on_no_match);
      }

      PushArgumentInstr* table_push =
          PushArgument(Bind(WordCharacterMapConstant()));
      PushArgumentInstr* index_push = PushLocal(current_character_);

      Definition* byte_def =
          InstanceCall(InstanceCallDescriptor::FromToken(Token::kINDEX),
                       table_push, index_push);
      Definition* zero_def = Int64Constant(0);

      BranchOrBacktrack(Comparison(kEQ, byte_def, zero_def), on_no_match);

      return true;
    }
    case 'W': {
      BlockLabel done;
      if (mode_ != ASCII) {
        // Table is 128 entries, so all ASCII characters can be tested.
        BranchOrBacktrack(
            Comparison(kGT, LoadLocal(current_character_), Uint64Constant('z')),
            &done);
      }

      // TODO(zerny): Refactor to use CheckBitInTable if possible.

      PushArgumentInstr* table_push =
          PushArgument(Bind(WordCharacterMapConstant()));
      PushArgumentInstr* index_push = PushLocal(current_character_);

      Definition* byte_def =
          InstanceCall(InstanceCallDescriptor::FromToken(Token::kINDEX),
                       table_push, index_push);
      Definition* zero_def = Int64Constant(0);

      BranchOrBacktrack(Comparison(kNE, byte_def, zero_def), on_no_match);

      if (mode_ != ASCII) {
        BindBlock(&done);
      }
      return true;
    }
    // Non-standard classes (with no syntactic shorthand) used internally.
    case '*':
      // Match any character.
      return true;
    case 'n': {
      // Match newlines (0x0a('\n'), 0x0d('\r'), 0x2028 or 0x2029).
      // The opposite of '.'.
      BlockLabel success;
      BranchOrBacktrack(
          Comparison(kEQ, LoadLocal(current_character_), Uint64Constant('\n')),
          &success);
      BranchOrBacktrack(
          Comparison(kEQ, LoadLocal(current_character_), Uint64Constant('\r')),
          &success);
      if (mode_ == UC16) {
        BranchOrBacktrack(Comparison(kEQ, LoadLocal(current_character_),
                                     Uint64Constant(0x2028)),
                          &success);
        BranchOrBacktrack(Comparison(kEQ, LoadLocal(current_character_),
                                     Uint64Constant(0x2029)),
                          &success);
      }
      BranchOrBacktrack(NULL, on_no_match);
      BindBlock(&success);
      return true;
    }
    // No custom implementation (yet): s(uint16_t), S(uint16_t).
    default:
      return false;
  }
}

void IRRegExpMacroAssembler::Fail() {
  TAG();
  ASSERT(FAILURE == 0);  // Return value for failure is zero.
  if (!global()) {
    UNREACHABLE();  // Dart regexps are always global.
  }
  GoTo(exit_block_);
}

void IRRegExpMacroAssembler::IfRegisterGE(intptr_t reg,
                                          intptr_t comparand,
                                          BlockLabel* if_ge) {
  TAG();
  PushArgumentInstr* reg_push = PushArgument(LoadRegister(reg));
  PushArgumentInstr* pos = PushArgument(Bind(Int64Constant(comparand)));
  BranchOrBacktrack(Comparison(kGTE, reg_push, pos), if_ge);
}

void IRRegExpMacroAssembler::IfRegisterLT(intptr_t reg,
                                          intptr_t comparand,
                                          BlockLabel* if_lt) {
  TAG();
  PushArgumentInstr* reg_push = PushArgument(LoadRegister(reg));
  PushArgumentInstr* pos = PushArgument(Bind(Int64Constant(comparand)));
  BranchOrBacktrack(Comparison(kLT, reg_push, pos), if_lt);
}

void IRRegExpMacroAssembler::IfRegisterEqPos(intptr_t reg, BlockLabel* if_eq) {
  TAG();
  PushArgumentInstr* reg_push = PushArgument(LoadRegister(reg));
  PushArgumentInstr* pos = PushArgument(Bind(LoadLocal(current_position_)));
  BranchOrBacktrack(Comparison(kEQ, reg_push, pos), if_eq);
}

RegExpMacroAssembler::IrregexpImplementation
IRRegExpMacroAssembler::Implementation() {
  return kIRImplementation;
}

void IRRegExpMacroAssembler::LoadCurrentCharacter(intptr_t cp_offset,
                                                  BlockLabel* on_end_of_input,
                                                  bool check_bounds,
                                                  intptr_t characters) {
  TAG();
  ASSERT(cp_offset < (1 << 30));  // Be sane! (And ensure negation works)
  if (check_bounds) {
    if (cp_offset >= 0) {
      CheckPosition(cp_offset + characters - 1, on_end_of_input);
    } else {
      CheckPosition(cp_offset, on_end_of_input);
    }
  }
  LoadCurrentCharacterUnchecked(cp_offset, characters);
}

void IRRegExpMacroAssembler::PopCurrentPosition() {
  TAG();
  StoreLocal(current_position_, Bind(PopStack()));
}

void IRRegExpMacroAssembler::PopRegister(intptr_t reg) {
  TAG();
  ASSERT(reg < registers_count_);
  PushArgumentInstr* registers_push = PushLocal(registers_);
  PushArgumentInstr* index_push = PushRegisterIndex(reg);
  PushArgumentInstr* pop_push = PushArgument(Bind(PopStack()));
  StoreRegister(registers_push, index_push, pop_push);
}

void IRRegExpMacroAssembler::PushStack(Definition* definition) {
  PushArgumentInstr* stack_push = PushLocal(stack_);
  PushArgumentInstr* stack_pointer_push = PushLocal(stack_pointer_);
  StoreLocal(stack_pointer_, Bind(Add(stack_pointer_push,
                                      PushArgument(Bind(Uint64Constant(1))))));
  stack_pointer_push = PushLocal(stack_pointer_);
  // TODO(zerny): bind value and push could break stack discipline.
  PushArgumentInstr* value_push = PushArgument(Bind(definition));
  Do(InstanceCall(InstanceCallDescriptor::FromToken(Token::kASSIGN_INDEX),
                  stack_push, stack_pointer_push, value_push));
}

Definition* IRRegExpMacroAssembler::PopStack() {
  PushArgumentInstr* stack_push = PushLocal(stack_);
  PushArgumentInstr* stack_pointer_push1 = PushLocal(stack_pointer_);
  PushArgumentInstr* stack_pointer_push2 = PushLocal(stack_pointer_);
  StoreLocal(stack_pointer_, Bind(Sub(stack_pointer_push2,
                                      PushArgument(Bind(Uint64Constant(1))))));
  return InstanceCall(InstanceCallDescriptor::FromToken(Token::kINDEX),
                      stack_push, stack_pointer_push1);
}

Definition* IRRegExpMacroAssembler::PeekStack() {
  PushArgumentInstr* stack_push = PushLocal(stack_);
  PushArgumentInstr* stack_pointer_push = PushLocal(stack_pointer_);
  return InstanceCall(InstanceCallDescriptor::FromToken(Token::kINDEX),
                      stack_push, stack_pointer_push);
}

// Pushes the location corresponding to label to the backtracking stack.
void IRRegExpMacroAssembler::PushBacktrack(BlockLabel* label) {
  TAG();

  // Ensure that targets of indirect jumps are never accessed through a
  // normal control flow instructions by creating a new block for each backtrack
  // target.
  IndirectEntryInstr* indirect_target = IndirectWithJoinGoto(label->block());

  // Add a fake edge from the graph entry for data flow analysis.
  entry_block_->AddIndirectEntry(indirect_target);

  ConstantInstr* offset = Uint64Constant(indirect_target->indirect_id());
  PushStack(offset);
  CheckStackLimit();
}

void IRRegExpMacroAssembler::PushCurrentPosition() {
  TAG();
  PushStack(LoadLocal(current_position_));
}

void IRRegExpMacroAssembler::PushRegister(intptr_t reg) {
  TAG();
  // TODO(zerny): Refactor PushStack so it can be reused here.
  PushArgumentInstr* stack_push = PushLocal(stack_);
  PushArgumentInstr* stack_pointer_push = PushLocal(stack_pointer_);
  StoreLocal(stack_pointer_, Bind(Add(stack_pointer_push,
                                      PushArgument(Bind(Uint64Constant(1))))));
  stack_pointer_push = PushLocal(stack_pointer_);
  // TODO(zerny): bind value and push could break stack discipline.
  PushArgumentInstr* value_push = PushArgument(LoadRegister(reg));
  Do(InstanceCall(InstanceCallDescriptor::FromToken(Token::kASSIGN_INDEX),
                  stack_push, stack_pointer_push, value_push));
  CheckStackLimit();
}

// Checks that (stack.capacity - stack_limit_slack) > stack_pointer.
// This ensures that up to stack_limit_slack stack pushes can be
// done without exhausting the stack space. If the check fails the
// stack will be grown.
void IRRegExpMacroAssembler::CheckStackLimit() {
  TAG();
  PushArgumentInstr* stack_push = PushLocal(stack_);
  PushArgumentInstr* length_push = PushArgument(
      Bind(InstanceCall(InstanceCallDescriptor(String::ZoneHandle(
                            Field::GetterSymbol(Symbols::Length()))),
                        stack_push)));
  PushArgumentInstr* capacity_push = PushArgument(Bind(Sub(
      length_push, PushArgument(Bind(Uint64Constant(stack_limit_slack()))))));
  PushArgumentInstr* stack_pointer_push = PushLocal(stack_pointer_);
  BranchInstr* branch = new (Z) BranchInstr(
      Comparison(kGT, capacity_push, stack_pointer_push), GetNextDeoptId());
  CloseBlockWith(branch);

  BlockLabel grow_stack;
  BlockLabel fallthrough;
  *branch->true_successor_address() = TargetWithJoinGoto(fallthrough.block());
  *branch->false_successor_address() = TargetWithJoinGoto(grow_stack.block());

  BindBlock(&grow_stack);
  GrowStack();

  BindBlock(&fallthrough);
}

void IRRegExpMacroAssembler::GrowStack() {
  TAG();
  const Library& lib = Library::Handle(Library::InternalLibrary());
  const Function& grow_function = Function::ZoneHandle(
      Z, lib.LookupFunctionAllowPrivate(Symbols::GrowRegExpStack()));
  StoreLocal(stack_, Bind(StaticCall(grow_function, PushLocal(stack_),
                                     ICData::kStatic)));

  // Note: :stack and stack_array_cell content might diverge because each
  // instance of :matcher code has its own stack_array_cell embedded into it
  // as a constant but :stack is a local variable and its value might be
  // comming from OSR or deoptimization. This means we should never use
  // stack_array_cell in the body of the :matcher to reload the :stack.
  PushArgumentInstr* stack_cell_push =
      PushArgument(Bind(new (Z) ConstantInstr(stack_array_cell_)));
  PushArgumentInstr* index_push = PushArgument(Bind(Uint64Constant(0)));
  PushArgumentInstr* stack_push = PushLocal(stack_);
  Do(InstanceCall(InstanceCallDescriptor::FromToken(Token::kASSIGN_INDEX),
                  stack_cell_push, index_push, stack_push));
}

void IRRegExpMacroAssembler::ReadCurrentPositionFromRegister(intptr_t reg) {
  TAG();
  StoreLocal(current_position_, LoadRegister(reg));
}

// Resets the tip of the stack to the value stored in reg.
void IRRegExpMacroAssembler::ReadStackPointerFromRegister(intptr_t reg) {
  TAG();
  ASSERT(reg < registers_count_);
  StoreLocal(stack_pointer_, LoadRegister(reg));
}

void IRRegExpMacroAssembler::SetCurrentPositionFromEnd(intptr_t by) {
  TAG();

  BlockLabel after_position;

  Definition* cur_pos_def = LoadLocal(current_position_);
  Definition* by_value_def = Int64Constant(-by);

  BranchOrBacktrack(Comparison(kGTE, cur_pos_def, by_value_def),
                    &after_position);

  StoreLocal(current_position_, Bind(Int64Constant(-by)));

  // On RegExp code entry (where this operation is used), the character before
  // the current position is expected to be already loaded.
  // We have advanced the position, so it's safe to read backwards.
  LoadCurrentCharacterUnchecked(-1, 1);

  BindBlock(&after_position);
}

void IRRegExpMacroAssembler::SetRegister(intptr_t reg, intptr_t to) {
  TAG();
  // Reserved for positions!
  ASSERT(reg >= saved_registers_count_);
  StoreRegister(reg, to);
}

bool IRRegExpMacroAssembler::Succeed() {
  TAG();
  GoTo(success_block_);
  return global();
}

void IRRegExpMacroAssembler::WriteCurrentPositionToRegister(
    intptr_t reg,
    intptr_t cp_offset) {
  TAG();

  PushArgumentInstr* registers_push = PushLocal(registers_);
  PushArgumentInstr* index_push = PushRegisterIndex(reg);
  PushArgumentInstr* pos_push = PushLocal(current_position_);
  PushArgumentInstr* off_push = PushArgument(Bind(Int64Constant(cp_offset)));
  PushArgumentInstr* neg_off_push = PushArgument(Bind(Add(pos_push, off_push)));
  // Push the negative offset; these are converted to positive string positions
  // within the success block.
  StoreRegister(registers_push, index_push, neg_off_push);
}

void IRRegExpMacroAssembler::ClearRegisters(intptr_t reg_from,
                                            intptr_t reg_to) {
  TAG();

  ASSERT(reg_from <= reg_to);

  // In order to clear registers to a final result value of -1, set them to
  // (-1 - string length), the offset of -1 from the end of the string.

  for (intptr_t reg = reg_from; reg <= reg_to; reg++) {
    PushArgumentInstr* registers_push = PushLocal(registers_);
    PushArgumentInstr* index_push = PushRegisterIndex(reg);
    PushArgumentInstr* minus_one_push = PushArgument(Bind(Int64Constant(-1)));
    PushArgumentInstr* length_push = PushLocal(string_param_length_);
    PushArgumentInstr* value_push =
        PushArgument(Bind(Sub(minus_one_push, length_push)));
    StoreRegister(registers_push, index_push, value_push);
  }
}

void IRRegExpMacroAssembler::WriteStackPointerToRegister(intptr_t reg) {
  TAG();

  PushArgumentInstr* registers_push = PushLocal(registers_);
  PushArgumentInstr* index_push = PushRegisterIndex(reg);
  PushArgumentInstr* tip_push = PushLocal(stack_pointer_);
  StoreRegister(registers_push, index_push, tip_push);
}

// Private methods:

void IRRegExpMacroAssembler::CheckPosition(intptr_t cp_offset,
                                           BlockLabel* on_outside_input) {
  TAG();
  if (cp_offset >= 0) {
    Definition* curpos_def = LoadLocal(current_position_);
    Definition* cp_off_def = Int64Constant(-cp_offset);
    // If (current_position_ < -cp_offset), we are in bounds.
    // Remember, current_position_ is a negative offset from the string end.

    BranchOrBacktrack(Comparison(kGTE, curpos_def, cp_off_def),
                      on_outside_input);
  } else {
    // We need to see if there's enough characters left in the string to go
    // back cp_offset characters, so get the normalized position and then
    // make sure that (normalized_position >= -cp_offset).
    PushArgumentInstr* pos_push = PushLocal(current_position_);
    PushArgumentInstr* len_push = PushLocal(string_param_length_);
    BranchOrBacktrack(
        Comparison(kLT, Add(pos_push, len_push), Uint64Constant(-cp_offset)),
        on_outside_input);
  }
}

void IRRegExpMacroAssembler::BranchOrBacktrack(ComparisonInstr* comparison,
                                               BlockLabel* true_successor) {
  if (comparison == NULL) {  // No condition
    if (true_successor == NULL) {
      Backtrack();
      return;
    }
    GoTo(true_successor);
    return;
  }

  // If no successor block has been passed in, backtrack.
  JoinEntryInstr* true_successor_block = backtrack_block_;
  if (true_successor != NULL) {
    true_successor->SetLinked();
    true_successor_block = true_successor->block();
  }
  ASSERT(true_successor_block != NULL);

  // If the condition is not true, fall through to a new block.
  BlockLabel fallthrough;

  BranchInstr* branch = new (Z) BranchInstr(comparison, GetNextDeoptId());
  *branch->true_successor_address() = TargetWithJoinGoto(true_successor_block);
  *branch->false_successor_address() = TargetWithJoinGoto(fallthrough.block());

  CloseBlockWith(branch);
  BindBlock(&fallthrough);
}

TargetEntryInstr* IRRegExpMacroAssembler::TargetWithJoinGoto(
    JoinEntryInstr* dst) {
  TargetEntryInstr* target = new (Z)
      TargetEntryInstr(block_id_.Alloc(), kInvalidTryIndex, GetNextDeoptId());
  blocks_.Add(target);

  target->AppendInstruction(new (Z) GotoInstr(dst, GetNextDeoptId()));

  return target;
}

IndirectEntryInstr* IRRegExpMacroAssembler::IndirectWithJoinGoto(
    JoinEntryInstr* dst) {
  IndirectEntryInstr* target =
      new (Z) IndirectEntryInstr(block_id_.Alloc(), indirect_id_.Alloc(),
                                 kInvalidTryIndex, GetNextDeoptId());
  blocks_.Add(target);

  target->AppendInstruction(new (Z) GotoInstr(dst, GetNextDeoptId()));

  return target;
}

void IRRegExpMacroAssembler::CheckPreemption(bool is_backtrack) {
  TAG();

  // We don't have the loop_depth available when compiling regexps, but
  // we set loop_depth to a non-zero value because this instruction does
  // not act as an OSR entry outside loops.
  AppendInstruction(new (Z) CheckStackOverflowInstr(
      TokenPosition::kNoSource,
      /*loop_depth=*/1, GetNextDeoptId(),
      is_backtrack ? CheckStackOverflowInstr::kOsrAndPreemption
                   : CheckStackOverflowInstr::kOsrOnly));
}

Definition* IRRegExpMacroAssembler::Add(PushArgumentInstr* lhs,
                                        PushArgumentInstr* rhs) {
  return InstanceCall(InstanceCallDescriptor::FromToken(Token::kADD), lhs, rhs);
}

Definition* IRRegExpMacroAssembler::Sub(PushArgumentInstr* lhs,
                                        PushArgumentInstr* rhs) {
  return InstanceCall(InstanceCallDescriptor::FromToken(Token::kSUB), lhs, rhs);
}

void IRRegExpMacroAssembler::LoadCurrentCharacterUnchecked(
    intptr_t cp_offset,
    intptr_t characters) {
  TAG();

  ASSERT(characters == 1 || CanReadUnaligned());
  if (mode_ == ASCII) {
    ASSERT(characters == 1 || characters == 2 || characters == 4);
  } else {
    ASSERT(mode_ == UC16);
    ASSERT(characters == 1 || characters == 2);
  }

  // Calculate the addressed string index as:
  //    cp_offset + current_position_ + string_param_length_
  // TODO(zerny): Avoid generating 'add' instance-calls here.
  PushArgumentInstr* off_arg = PushArgument(Bind(Int64Constant(cp_offset)));
  PushArgumentInstr* pos_arg = PushArgument(BindLoadLocal(*current_position_));
  PushArgumentInstr* off_pos_arg = PushArgument(Bind(Add(off_arg, pos_arg)));
  PushArgumentInstr* len_arg =
      PushArgument(BindLoadLocal(*string_param_length_));
  // Index is stored in a temporary local so that we can later load it safely.
  StoreLocal(index_temp_, Bind(Add(off_pos_arg, len_arg)));

  // Load and store the code units.
  Value* code_unit_value = LoadCodeUnitsAt(index_temp_, characters);
  StoreLocal(current_character_, code_unit_value);
  PRINT(PushLocal(current_character_));
}

Value* IRRegExpMacroAssembler::CharacterAt(LocalVariable* index) {
  return LoadCodeUnitsAt(index, 1);
}

Value* IRRegExpMacroAssembler::LoadCodeUnitsAt(LocalVariable* index,
                                               intptr_t characters) {
  // Bind the pattern as the load receiver.
  Value* pattern_val = BindLoadLocal(*string_param_);
  if (RawObject::IsExternalStringClassId(specialization_cid_)) {
    // The data of an external string is stored through one indirection.
    intptr_t external_offset = 0;
    if (specialization_cid_ == kExternalOneByteStringCid) {
      external_offset = ExternalOneByteString::external_data_offset();
    } else if (specialization_cid_ == kExternalTwoByteStringCid) {
      external_offset = ExternalTwoByteString::external_data_offset();
    } else {
      UNREACHABLE();
    }
    // This pushes an untagged value on the stack which is immediately consumed
    // by LoadCodeUnitsAtInstr below.
    pattern_val = Bind(new (Z) LoadUntaggedInstr(pattern_val, external_offset));
  }

  // Here pattern_val might be untagged so this must not trigger a GC.
  Value* index_val = BindLoadLocal(*index);

  return Bind(new (Z) LoadCodeUnitsInstr(pattern_val, index_val, characters,
                                         specialization_cid_,
                                         TokenPosition::kNoSource));
}

#undef __

}  // namespace dart

#endif  // !defined(DART_PRECOMPILED_RUNTIME)
