// Copyright (c) 1994-2006 Sun Microsystems Inc.
// 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.
//
// - Redistribution 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 Sun Microsystems or the names of 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.

// The original source code covered by the above license above has been
// modified significantly by Google Inc.
// Copyright 2006-2009 the V8 project authors. All rights reserved.

#include "v8.h"

#include "arguments.h"
#include "execution.h"
#include "ic-inl.h"
#include "factory.h"
#include "runtime.h"
#include "serialize.h"
#include "stub-cache.h"
#include "regexp-stack.h"
#include "ast.h"
#include "regexp-macro-assembler.h"
#include "platform.h"
// Include native regexp-macro-assembler.
#ifndef V8_INTERPRETED_REGEXP
#if V8_TARGET_ARCH_IA32
#include "ia32/regexp-macro-assembler-ia32.h"
#elif V8_TARGET_ARCH_X64
#include "x64/regexp-macro-assembler-x64.h"
#elif V8_TARGET_ARCH_ARM
#include "arm/regexp-macro-assembler-arm.h"
#else  // Unknown architecture.
#error "Unknown architecture."
#endif  // Target architecture.
#endif  // V8_INTERPRETED_REGEXP

namespace v8 {
namespace internal {


// -----------------------------------------------------------------------------
// Implementation of Label

int Label::pos() const {
  if (pos_ < 0) return -pos_ - 1;
  if (pos_ > 0) return  pos_ - 1;
  UNREACHABLE();
  return 0;
}


// -----------------------------------------------------------------------------
// Implementation of RelocInfoWriter and RelocIterator
//
// Encoding
//
// The most common modes are given single-byte encodings.  Also, it is
// easy to identify the type of reloc info and skip unwanted modes in
// an iteration.
//
// The encoding relies on the fact that there are less than 14
// different relocation modes.
//
// embedded_object:    [6 bits pc delta] 00
//
// code_taget:         [6 bits pc delta] 01
//
// position:           [6 bits pc delta] 10,
//                     [7 bits signed data delta] 0
//
// statement_position: [6 bits pc delta] 10,
//                     [7 bits signed data delta] 1
//
// any nondata mode:   00 [4 bits rmode] 11,  // rmode: 0..13 only
//                     00 [6 bits pc delta]
//
// pc-jump:            00 1111 11,
//                     00 [6 bits pc delta]
//
// pc-jump:            01 1111 11,
// (variable length)   7 - 26 bit pc delta, written in chunks of 7
//                     bits, the lowest 7 bits written first.
//
// data-jump + pos:    00 1110 11,
//                     signed intptr_t, lowest byte written first
//
// data-jump + st.pos: 01 1110 11,
//                     signed intptr_t, lowest byte written first
//
// data-jump + comm.:  10 1110 11,
//                     signed intptr_t, lowest byte written first
//
const int kMaxRelocModes = 14;

const int kTagBits = 2;
const int kTagMask = (1 << kTagBits) - 1;
const int kExtraTagBits = 4;
const int kPositionTypeTagBits = 1;
const int kSmallDataBits = kBitsPerByte - kPositionTypeTagBits;

const int kEmbeddedObjectTag = 0;
const int kCodeTargetTag = 1;
const int kPositionTag = 2;
const int kDefaultTag = 3;

const int kPCJumpTag = (1 << kExtraTagBits) - 1;

const int kSmallPCDeltaBits = kBitsPerByte - kTagBits;
const int kSmallPCDeltaMask = (1 << kSmallPCDeltaBits) - 1;

const int kVariableLengthPCJumpTopTag = 1;
const int kChunkBits = 7;
const int kChunkMask = (1 << kChunkBits) - 1;
const int kLastChunkTagBits = 1;
const int kLastChunkTagMask = 1;
const int kLastChunkTag = 1;


const int kDataJumpTag = kPCJumpTag - 1;

const int kNonstatementPositionTag = 0;
const int kStatementPositionTag = 1;
const int kCommentTag = 2;


uint32_t RelocInfoWriter::WriteVariableLengthPCJump(uint32_t pc_delta) {
  // Return if the pc_delta can fit in kSmallPCDeltaBits bits.
  // Otherwise write a variable length PC jump for the bits that do
  // not fit in the kSmallPCDeltaBits bits.
  if (is_uintn(pc_delta, kSmallPCDeltaBits)) return pc_delta;
  WriteExtraTag(kPCJumpTag, kVariableLengthPCJumpTopTag);
  uint32_t pc_jump = pc_delta >> kSmallPCDeltaBits;
  ASSERT(pc_jump > 0);
  // Write kChunkBits size chunks of the pc_jump.
  for (; pc_jump > 0; pc_jump = pc_jump >> kChunkBits) {
    byte b = pc_jump & kChunkMask;
    *--pos_ = b << kLastChunkTagBits;
  }
  // Tag the last chunk so it can be identified.
  *pos_ = *pos_ | kLastChunkTag;
  // Return the remaining kSmallPCDeltaBits of the pc_delta.
  return pc_delta & kSmallPCDeltaMask;
}


void RelocInfoWriter::WriteTaggedPC(uint32_t pc_delta, int tag) {
  // Write a byte of tagged pc-delta, possibly preceded by var. length pc-jump.
  pc_delta = WriteVariableLengthPCJump(pc_delta);
  *--pos_ = pc_delta << kTagBits | tag;
}


void RelocInfoWriter::WriteTaggedData(intptr_t data_delta, int tag) {
  *--pos_ = static_cast<byte>(data_delta << kPositionTypeTagBits | tag);
}


void RelocInfoWriter::WriteExtraTag(int extra_tag, int top_tag) {
  *--pos_ = static_cast<int>(top_tag << (kTagBits + kExtraTagBits) |
                             extra_tag << kTagBits |
                             kDefaultTag);
}


void RelocInfoWriter::WriteExtraTaggedPC(uint32_t pc_delta, int extra_tag) {
  // Write two-byte tagged pc-delta, possibly preceded by var. length pc-jump.
  pc_delta = WriteVariableLengthPCJump(pc_delta);
  WriteExtraTag(extra_tag, 0);
  *--pos_ = pc_delta;
}


void RelocInfoWriter::WriteExtraTaggedData(intptr_t data_delta, int top_tag) {
  WriteExtraTag(kDataJumpTag, top_tag);
  for (int i = 0; i < kIntptrSize; i++) {
    *--pos_ = static_cast<byte>(data_delta);
  // Signed right shift is arithmetic shift.  Tested in test-utils.cc.
    data_delta = data_delta >> kBitsPerByte;
  }
}


void RelocInfoWriter::Write(const RelocInfo* rinfo) {
#ifdef DEBUG
  byte* begin_pos = pos_;
#endif
  Counters::reloc_info_count.Increment();
  ASSERT(rinfo->pc() - last_pc_ >= 0);
  ASSERT(RelocInfo::NUMBER_OF_MODES < kMaxRelocModes);
  // Use unsigned delta-encoding for pc.
  uint32_t pc_delta = static_cast<uint32_t>(rinfo->pc() - last_pc_);
  RelocInfo::Mode rmode = rinfo->rmode();

  // The two most common modes are given small tags, and usually fit in a byte.
  if (rmode == RelocInfo::EMBEDDED_OBJECT) {
    WriteTaggedPC(pc_delta, kEmbeddedObjectTag);
  } else if (rmode == RelocInfo::CODE_TARGET) {
    WriteTaggedPC(pc_delta, kCodeTargetTag);
  } else if (RelocInfo::IsPosition(rmode)) {
    // Use signed delta-encoding for data.
    intptr_t data_delta = rinfo->data() - last_data_;
    int pos_type_tag = rmode == RelocInfo::POSITION ? kNonstatementPositionTag
                                                    : kStatementPositionTag;
    // Check if data is small enough to fit in a tagged byte.
    // We cannot use is_intn because data_delta is not an int32_t.
    if (data_delta >= -(1 << (kSmallDataBits-1)) &&
        data_delta < 1 << (kSmallDataBits-1)) {
      WriteTaggedPC(pc_delta, kPositionTag);
      WriteTaggedData(data_delta, pos_type_tag);
      last_data_ = rinfo->data();
    } else {
      // Otherwise, use costly encoding.
      WriteExtraTaggedPC(pc_delta, kPCJumpTag);
      WriteExtraTaggedData(data_delta, pos_type_tag);
      last_data_ = rinfo->data();
    }
  } else if (RelocInfo::IsComment(rmode)) {
    // Comments are normally not generated, so we use the costly encoding.
    WriteExtraTaggedPC(pc_delta, kPCJumpTag);
    WriteExtraTaggedData(rinfo->data() - last_data_, kCommentTag);
    last_data_ = rinfo->data();
  } else {
    // For all other modes we simply use the mode as the extra tag.
    // None of these modes need a data component.
    ASSERT(rmode < kPCJumpTag && rmode < kDataJumpTag);
    WriteExtraTaggedPC(pc_delta, rmode);
  }
  last_pc_ = rinfo->pc();
#ifdef DEBUG
  ASSERT(begin_pos - pos_ <= kMaxSize);
#endif
}


inline int RelocIterator::AdvanceGetTag() {
  return *--pos_ & kTagMask;
}


inline int RelocIterator::GetExtraTag() {
  return (*pos_ >> kTagBits) & ((1 << kExtraTagBits) - 1);
}


inline int RelocIterator::GetTopTag() {
  return *pos_ >> (kTagBits + kExtraTagBits);
}


inline void RelocIterator::ReadTaggedPC() {
  rinfo_.pc_ += *pos_ >> kTagBits;
}


inline void RelocIterator::AdvanceReadPC() {
  rinfo_.pc_ += *--pos_;
}


void RelocIterator::AdvanceReadData() {
  intptr_t x = 0;
  for (int i = 0; i < kIntptrSize; i++) {
    x |= static_cast<intptr_t>(*--pos_) << i * kBitsPerByte;
  }
  rinfo_.data_ += x;
}


void RelocIterator::AdvanceReadVariableLengthPCJump() {
  // Read the 32-kSmallPCDeltaBits most significant bits of the
  // pc jump in kChunkBits bit chunks and shift them into place.
  // Stop when the last chunk is encountered.
  uint32_t pc_jump = 0;
  for (int i = 0; i < kIntSize; i++) {
    byte pc_jump_part = *--pos_;
    pc_jump |= (pc_jump_part >> kLastChunkTagBits) << i * kChunkBits;
    if ((pc_jump_part & kLastChunkTagMask) == 1) break;
  }
  // The least significant kSmallPCDeltaBits bits will be added
  // later.
  rinfo_.pc_ += pc_jump << kSmallPCDeltaBits;
}


inline int RelocIterator::GetPositionTypeTag() {
  return *pos_ & ((1 << kPositionTypeTagBits) - 1);
}


inline void RelocIterator::ReadTaggedData() {
  int8_t signed_b = *pos_;
  // Signed right shift is arithmetic shift.  Tested in test-utils.cc.
  rinfo_.data_ += signed_b >> kPositionTypeTagBits;
}


inline RelocInfo::Mode RelocIterator::DebugInfoModeFromTag(int tag) {
  if (tag == kStatementPositionTag) {
    return RelocInfo::STATEMENT_POSITION;
  } else if (tag == kNonstatementPositionTag) {
    return RelocInfo::POSITION;
  } else {
    ASSERT(tag == kCommentTag);
    return RelocInfo::COMMENT;
  }
}


void RelocIterator::next() {
  ASSERT(!done());
  // Basically, do the opposite of RelocInfoWriter::Write.
  // Reading of data is as far as possible avoided for unwanted modes,
  // but we must always update the pc.
  //
  // We exit this loop by returning when we find a mode we want.
  while (pos_ > end_) {
    int tag = AdvanceGetTag();
    if (tag == kEmbeddedObjectTag) {
      ReadTaggedPC();
      if (SetMode(RelocInfo::EMBEDDED_OBJECT)) return;
    } else if (tag == kCodeTargetTag) {
      ReadTaggedPC();
      if (SetMode(RelocInfo::CODE_TARGET)) return;
    } else if (tag == kPositionTag) {
      ReadTaggedPC();
      Advance();
      // Check if we want source positions.
      if (mode_mask_ & RelocInfo::kPositionMask) {
        // Check if we want this type of source position.
        if (SetMode(DebugInfoModeFromTag(GetPositionTypeTag()))) {
          // Finally read the data before returning.
          ReadTaggedData();
          return;
        }
      }
    } else {
      ASSERT(tag == kDefaultTag);
      int extra_tag = GetExtraTag();
      if (extra_tag == kPCJumpTag) {
        int top_tag = GetTopTag();
        if (top_tag == kVariableLengthPCJumpTopTag) {
          AdvanceReadVariableLengthPCJump();
        } else {
          AdvanceReadPC();
        }
      } else if (extra_tag == kDataJumpTag) {
        // Check if we want debug modes (the only ones with data).
        if (mode_mask_ & RelocInfo::kDebugMask) {
          int top_tag = GetTopTag();
          AdvanceReadData();
          if (SetMode(DebugInfoModeFromTag(top_tag))) return;
        } else {
          // Otherwise, just skip over the data.
          Advance(kIntptrSize);
        }
      } else {
        AdvanceReadPC();
        if (SetMode(static_cast<RelocInfo::Mode>(extra_tag))) return;
      }
    }
  }
  done_ = true;
}


RelocIterator::RelocIterator(Code* code, int mode_mask) {
  rinfo_.pc_ = code->instruction_start();
  rinfo_.data_ = 0;
  // relocation info is read backwards
  pos_ = code->relocation_start() + code->relocation_size();
  end_ = code->relocation_start();
  done_ = false;
  mode_mask_ = mode_mask;
  if (mode_mask_ == 0) pos_ = end_;
  next();
}


RelocIterator::RelocIterator(const CodeDesc& desc, int mode_mask) {
  rinfo_.pc_ = desc.buffer;
  rinfo_.data_ = 0;
  // relocation info is read backwards
  pos_ = desc.buffer + desc.buffer_size;
  end_ = pos_ - desc.reloc_size;
  done_ = false;
  mode_mask_ = mode_mask;
  if (mode_mask_ == 0) pos_ = end_;
  next();
}


// -----------------------------------------------------------------------------
// Implementation of RelocInfo


#ifdef ENABLE_DISASSEMBLER
const char* RelocInfo::RelocModeName(RelocInfo::Mode rmode) {
  switch (rmode) {
    case RelocInfo::NONE:
      return "no reloc";
    case RelocInfo::EMBEDDED_OBJECT:
      return "embedded object";
    case RelocInfo::EMBEDDED_STRING:
      return "embedded string";
    case RelocInfo::CONSTRUCT_CALL:
      return "code target (js construct call)";
    case RelocInfo::CODE_TARGET_CONTEXT:
      return "code target (context)";
    case RelocInfo::DEBUG_BREAK:
#ifndef ENABLE_DEBUGGER_SUPPORT
      UNREACHABLE();
#endif
      return "debug break";
    case RelocInfo::CODE_TARGET:
      return "code target";
    case RelocInfo::RUNTIME_ENTRY:
      return "runtime entry";
    case RelocInfo::JS_RETURN:
      return "js return";
    case RelocInfo::COMMENT:
      return "comment";
    case RelocInfo::POSITION:
      return "position";
    case RelocInfo::STATEMENT_POSITION:
      return "statement position";
    case RelocInfo::EXTERNAL_REFERENCE:
      return "external reference";
    case RelocInfo::INTERNAL_REFERENCE:
      return "internal reference";
    case RelocInfo::NUMBER_OF_MODES:
      UNREACHABLE();
      return "number_of_modes";
  }
  return "unknown relocation type";
}


void RelocInfo::Print() {
  PrintF("%p  %s", pc_, RelocModeName(rmode_));
  if (IsComment(rmode_)) {
    PrintF("  (%s)", data_);
  } else if (rmode_ == EMBEDDED_OBJECT) {
    PrintF("  (");
    target_object()->ShortPrint();
    PrintF(")");
  } else if (rmode_ == EXTERNAL_REFERENCE) {
    ExternalReferenceEncoder ref_encoder;
    PrintF(" (%s)  (%p)",
           ref_encoder.NameOfAddress(*target_reference_address()),
           *target_reference_address());
  } else if (IsCodeTarget(rmode_)) {
    Code* code = Code::GetCodeFromTargetAddress(target_address());
    PrintF(" (%s)  (%p)", Code::Kind2String(code->kind()), target_address());
  } else if (IsPosition(rmode_)) {
    PrintF("  (%d)", data());
  }

  PrintF("\n");
}
#endif  // ENABLE_DISASSEMBLER


#ifdef DEBUG
void RelocInfo::Verify() {
  switch (rmode_) {
    case EMBEDDED_OBJECT:
      Object::VerifyPointer(target_object());
      break;
    case DEBUG_BREAK:
#ifndef ENABLE_DEBUGGER_SUPPORT
      UNREACHABLE();
      break;
#endif
    case CONSTRUCT_CALL:
    case CODE_TARGET_CONTEXT:
    case CODE_TARGET: {
      // convert inline target address to code object
      Address addr = target_address();
      ASSERT(addr != NULL);
      // Check that we can find the right code object.
      Code* code = Code::GetCodeFromTargetAddress(addr);
      Object* found = Heap::FindCodeObject(addr);
      ASSERT(found->IsCode());
      ASSERT(code->address() == HeapObject::cast(found)->address());
      break;
    }
    case RelocInfo::EMBEDDED_STRING:
    case RUNTIME_ENTRY:
    case JS_RETURN:
    case COMMENT:
    case POSITION:
    case STATEMENT_POSITION:
    case EXTERNAL_REFERENCE:
    case INTERNAL_REFERENCE:
    case NONE:
      break;
    case NUMBER_OF_MODES:
      UNREACHABLE();
      break;
  }
}
#endif  // DEBUG


// -----------------------------------------------------------------------------
// Implementation of ExternalReference

ExternalReference::ExternalReference(Builtins::CFunctionId id)
  : address_(Redirect(Builtins::c_function_address(id))) {}


ExternalReference::ExternalReference(ApiFunction* fun)
  : address_(Redirect(fun->address())) {}


ExternalReference::ExternalReference(Builtins::Name name)
  : address_(Builtins::builtin_address(name)) {}


ExternalReference::ExternalReference(Runtime::FunctionId id)
  : address_(Redirect(Runtime::FunctionForId(id)->entry)) {}


ExternalReference::ExternalReference(Runtime::Function* f)
  : address_(Redirect(f->entry)) {}


ExternalReference::ExternalReference(const IC_Utility& ic_utility)
  : address_(Redirect(ic_utility.address())) {}

#ifdef ENABLE_DEBUGGER_SUPPORT
ExternalReference::ExternalReference(const Debug_Address& debug_address)
  : address_(debug_address.address()) {}
#endif

ExternalReference::ExternalReference(StatsCounter* counter)
  : address_(reinterpret_cast<Address>(counter->GetInternalPointer())) {}


ExternalReference::ExternalReference(Top::AddressId id)
  : address_(Top::get_address_from_id(id)) {}


ExternalReference::ExternalReference(const SCTableReference& table_ref)
  : address_(table_ref.address()) {}


ExternalReference ExternalReference::perform_gc_function() {
  return ExternalReference(Redirect(FUNCTION_ADDR(Runtime::PerformGC)));
}


ExternalReference ExternalReference::fill_heap_number_with_random_function() {
  return
      ExternalReference(Redirect(FUNCTION_ADDR(V8::FillHeapNumberWithRandom)));
}


ExternalReference ExternalReference::random_uint32_function() {
  return ExternalReference(Redirect(FUNCTION_ADDR(V8::Random)));
}


ExternalReference ExternalReference::transcendental_cache_array_address() {
  return ExternalReference(TranscendentalCache::cache_array_address());
}


ExternalReference ExternalReference::keyed_lookup_cache_keys() {
  return ExternalReference(KeyedLookupCache::keys_address());
}


ExternalReference ExternalReference::keyed_lookup_cache_field_offsets() {
  return ExternalReference(KeyedLookupCache::field_offsets_address());
}


ExternalReference ExternalReference::the_hole_value_location() {
  return ExternalReference(Factory::the_hole_value().location());
}


ExternalReference ExternalReference::roots_address() {
  return ExternalReference(Heap::roots_address());
}


ExternalReference ExternalReference::address_of_stack_limit() {
  return ExternalReference(StackGuard::address_of_jslimit());
}


ExternalReference ExternalReference::address_of_real_stack_limit() {
  return ExternalReference(StackGuard::address_of_real_jslimit());
}


ExternalReference ExternalReference::address_of_regexp_stack_limit() {
  return ExternalReference(RegExpStack::limit_address());
}


ExternalReference ExternalReference::new_space_start() {
  return ExternalReference(Heap::NewSpaceStart());
}


ExternalReference ExternalReference::new_space_mask() {
  return ExternalReference(reinterpret_cast<Address>(Heap::NewSpaceMask()));
}


ExternalReference ExternalReference::new_space_allocation_top_address() {
  return ExternalReference(Heap::NewSpaceAllocationTopAddress());
}


ExternalReference ExternalReference::heap_always_allocate_scope_depth() {
  return ExternalReference(Heap::always_allocate_scope_depth_address());
}


ExternalReference ExternalReference::new_space_allocation_limit_address() {
  return ExternalReference(Heap::NewSpaceAllocationLimitAddress());
}


ExternalReference ExternalReference::handle_scope_extensions_address() {
  return ExternalReference(HandleScope::current_extensions_address());
}


ExternalReference ExternalReference::handle_scope_next_address() {
  return ExternalReference(HandleScope::current_next_address());
}


ExternalReference ExternalReference::handle_scope_limit_address() {
  return ExternalReference(HandleScope::current_limit_address());
}


ExternalReference ExternalReference::scheduled_exception_address() {
  return ExternalReference(Top::scheduled_exception_address());
}


#ifndef V8_INTERPRETED_REGEXP

ExternalReference ExternalReference::re_check_stack_guard_state() {
  Address function;
#ifdef V8_TARGET_ARCH_X64
  function = FUNCTION_ADDR(RegExpMacroAssemblerX64::CheckStackGuardState);
#elif V8_TARGET_ARCH_IA32
  function = FUNCTION_ADDR(RegExpMacroAssemblerIA32::CheckStackGuardState);
#elif V8_TARGET_ARCH_ARM
  function = FUNCTION_ADDR(RegExpMacroAssemblerARM::CheckStackGuardState);
#else
  UNREACHABLE();
#endif
  return ExternalReference(Redirect(function));
}

ExternalReference ExternalReference::re_grow_stack() {
  return ExternalReference(
      Redirect(FUNCTION_ADDR(NativeRegExpMacroAssembler::GrowStack)));
}

ExternalReference ExternalReference::re_case_insensitive_compare_uc16() {
  return ExternalReference(Redirect(
      FUNCTION_ADDR(NativeRegExpMacroAssembler::CaseInsensitiveCompareUC16)));
}

ExternalReference ExternalReference::re_word_character_map() {
  return ExternalReference(
      NativeRegExpMacroAssembler::word_character_map_address());
}

ExternalReference ExternalReference::address_of_static_offsets_vector() {
  return ExternalReference(OffsetsVector::static_offsets_vector_address());
}

ExternalReference ExternalReference::address_of_regexp_stack_memory_address() {
  return ExternalReference(RegExpStack::memory_address());
}

ExternalReference ExternalReference::address_of_regexp_stack_memory_size() {
  return ExternalReference(RegExpStack::memory_size_address());
}

#endif  // V8_INTERPRETED_REGEXP


static double add_two_doubles(double x, double y) {
  return x + y;
}


static double sub_two_doubles(double x, double y) {
  return x - y;
}


static double mul_two_doubles(double x, double y) {
  return x * y;
}


static double div_two_doubles(double x, double y) {
  return x / y;
}


static double mod_two_doubles(double x, double y) {
  return modulo(x, y);
}


static int native_compare_doubles(double y, double x) {
  if (x == y) return EQUAL;
  return x < y ? LESS : GREATER;
}


ExternalReference ExternalReference::double_fp_operation(
    Token::Value operation) {
  typedef double BinaryFPOperation(double x, double y);
  BinaryFPOperation* function = NULL;
  switch (operation) {
    case Token::ADD:
      function = &add_two_doubles;
      break;
    case Token::SUB:
      function = &sub_two_doubles;
      break;
    case Token::MUL:
      function = &mul_two_doubles;
      break;
    case Token::DIV:
      function = &div_two_doubles;
      break;
    case Token::MOD:
      function = &mod_two_doubles;
      break;
    default:
      UNREACHABLE();
  }
  // Passing true as 2nd parameter indicates that they return an fp value.
  return ExternalReference(Redirect(FUNCTION_ADDR(function), true));
}


ExternalReference ExternalReference::compare_doubles() {
  return ExternalReference(Redirect(FUNCTION_ADDR(native_compare_doubles),
                                    false));
}


ExternalReferenceRedirector* ExternalReference::redirector_ = NULL;


#ifdef ENABLE_DEBUGGER_SUPPORT
ExternalReference ExternalReference::debug_break() {
  return ExternalReference(Redirect(FUNCTION_ADDR(Debug::Break)));
}


ExternalReference ExternalReference::debug_step_in_fp_address() {
  return ExternalReference(Debug::step_in_fp_addr());
}
#endif

} }  // namespace v8::internal
