普通文本  |  479行  |  13.28 KB

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

#include "v8.h"

#if defined(V8_TARGET_ARCH_MIPS)

#include "unicode.h"
#include "log.h"
#include "code-stubs.h"
#include "regexp-stack.h"
#include "macro-assembler.h"
#include "regexp-macro-assembler.h"
#include "mips/regexp-macro-assembler-mips.h"

namespace v8 {
namespace internal {

#ifndef V8_INTERPRETED_REGEXP
/*
 * This assembler uses the following register assignment convention
 * - t1 : Pointer to current code object (Code*) including heap object tag.
 * - t2 : Current position in input, as negative offset from end of string.
 *        Please notice that this is the byte offset, not the character offset!
 * - t3 : Currently loaded character. Must be loaded using
 *        LoadCurrentCharacter before using any of the dispatch methods.
 * - t4 : points to tip of backtrack stack
 * - t5 : Unused.
 * - t6 : End of input (points to byte after last character in input).
 * - fp : Frame pointer. Used to access arguments, local variables and
 *         RegExp registers.
 * - sp : points to tip of C stack.
 *
 * The remaining registers are free for computations.
 *
 * Each call to a public method should retain this convention.
 * The stack will have the following structure:
 *       - direct_call        (if 1, direct call from JavaScript code, if 0 call
 *                             through the runtime system)
 *       - stack_area_base    (High end of the memory area to use as
 *                             backtracking stack)
 *       - int* capture_array (int[num_saved_registers_], for output).
 *       - stack frame header (16 bytes in size)
 *       --- sp when called ---
 *       - link address
 *       - backup of registers s0..s7
 *       - end of input       (Address of end of string)
 *       - start of input     (Address of first character in string)
 *       - start index        (character index of start)
 *       --- frame pointer ----
 *       - void* input_string (location of a handle containing the string)
 *       - Offset of location before start of input (effectively character
 *         position -1). Used to initialize capture registers to a non-position.
 *       - At start (if 1, we are starting at the start of the
 *         string, otherwise 0)
 *       - register 0         (Only positions must be stored in the first
 *       - register 1          num_saved_registers_ registers)
 *       - ...
 *       - register num_registers-1
 *       --- sp ---
 *
 * The first num_saved_registers_ registers are initialized to point to
 * "character -1" in the string (i.e., char_size() bytes before the first
 * character of the string). The remaining registers start out as garbage.
 *
 * The data up to the return address must be placed there by the calling
 * code, by calling the code entry as cast to a function with the signature:
 * int (*match)(String* input_string,
 *              int start_index,
 *              Address start,
 *              Address end,
 *              int* capture_output_array,
 *              bool at_start,
 *              byte* stack_area_base,
 *              bool direct_call)
 * The call is performed by NativeRegExpMacroAssembler::Execute()
 * (in regexp-macro-assembler.cc).
 */

#define __ ACCESS_MASM(masm_)

RegExpMacroAssemblerMIPS::RegExpMacroAssemblerMIPS(
    Mode mode,
    int registers_to_save)
    : masm_(new MacroAssembler(NULL, kRegExpCodeSize)),
      mode_(mode),
      num_registers_(registers_to_save),
      num_saved_registers_(registers_to_save),
      entry_label_(),
      start_label_(),
      success_label_(),
      backtrack_label_(),
      exit_label_() {
  ASSERT_EQ(0, registers_to_save % 2);
  __ jmp(&entry_label_);   // We'll write the entry code later.
  __ bind(&start_label_);  // And then continue from here.
}


RegExpMacroAssemblerMIPS::~RegExpMacroAssemblerMIPS() {
  delete masm_;
  // Unuse labels in case we throw away the assembler without calling GetCode.
  entry_label_.Unuse();
  start_label_.Unuse();
  success_label_.Unuse();
  backtrack_label_.Unuse();
  exit_label_.Unuse();
  check_preempt_label_.Unuse();
  stack_overflow_label_.Unuse();
}


int RegExpMacroAssemblerMIPS::stack_limit_slack()  {
  return RegExpStack::kStackLimitSlack;
}


void RegExpMacroAssemblerMIPS::AdvanceCurrentPosition(int by) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::AdvanceRegister(int reg, int by) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::Backtrack() {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::Bind(Label* label) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::CheckCharacter(uint32_t c, Label* on_equal) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::CheckCharacterGT(uc16 limit, Label* on_greater) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::CheckAtStart(Label* on_at_start) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::CheckNotAtStart(Label* on_not_at_start) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::CheckCharacterLT(uc16 limit, Label* on_less) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::CheckCharacters(Vector<const uc16> str,
                                              int cp_offset,
                                              Label* on_failure,
                                              bool check_end_of_string) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::CheckGreedyLoop(Label* on_equal) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase(
    int start_reg,
    Label* on_no_match) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::CheckNotBackReference(
    int start_reg,
    Label* on_no_match) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::CheckNotRegistersEqual(int reg1,
                                                      int reg2,
                                                      Label* on_not_equal) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::CheckNotCharacter(uint32_t c,
                                                Label* on_not_equal) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::CheckCharacterAfterAnd(uint32_t c,
                                                     uint32_t mask,
                                                     Label* on_equal) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::CheckNotCharacterAfterAnd(uint32_t c,
                                                        uint32_t mask,
                                                        Label* on_not_equal) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::CheckNotCharacterAfterMinusAnd(
    uc16 c,
    uc16 minus,
    uc16 mask,
    Label* on_not_equal) {
  UNIMPLEMENTED_MIPS();
}


bool RegExpMacroAssemblerMIPS::CheckSpecialCharacterClass(uc16 type,
                                                         Label* on_no_match) {
  UNIMPLEMENTED_MIPS();
  return false;
}


void RegExpMacroAssemblerMIPS::Fail() {
  UNIMPLEMENTED_MIPS();
}


Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
  UNIMPLEMENTED_MIPS();
  return Handle<HeapObject>::null();
}


void RegExpMacroAssemblerMIPS::GoTo(Label* to) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::IfRegisterGE(int reg,
                                           int comparand,
                                           Label* if_ge) {
  __ lw(a0, register_location(reg));
    BranchOrBacktrack(if_ge, ge, a0, Operand(comparand));
}


void RegExpMacroAssemblerMIPS::IfRegisterLT(int reg,
                                           int comparand,
                                           Label* if_lt) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::IfRegisterEqPos(int reg,
                                              Label* if_eq) {
  UNIMPLEMENTED_MIPS();
}


RegExpMacroAssembler::IrregexpImplementation
    RegExpMacroAssemblerMIPS::Implementation() {
  return kMIPSImplementation;
}


void RegExpMacroAssemblerMIPS::LoadCurrentCharacter(int cp_offset,
                                                   Label* on_end_of_input,
                                                   bool check_bounds,
                                                   int characters) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::PopCurrentPosition() {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::PopRegister(int register_index) {
  UNIMPLEMENTED_MIPS();
}



void RegExpMacroAssemblerMIPS::PushBacktrack(Label* label) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::PushCurrentPosition() {
  Push(current_input_offset());
}


void RegExpMacroAssemblerMIPS::PushRegister(int register_index,
                                           StackCheckFlag check_stack_limit) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::ReadCurrentPositionFromRegister(int reg) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::ReadStackPointerFromRegister(int reg) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::SetCurrentPositionFromEnd(int by) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::SetRegister(int register_index, int to) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::Succeed() {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::WriteCurrentPositionToRegister(int reg,
                                                             int cp_offset) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::ClearRegisters(int reg_from, int reg_to) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(int reg) {
  UNIMPLEMENTED_MIPS();
}


// Private methods:

void RegExpMacroAssemblerMIPS::CallCheckStackGuardState(Register scratch) {
  UNIMPLEMENTED_MIPS();
}


// Helper function for reading a value out of a stack frame.
template <typename T>
static T& frame_entry(Address re_frame, int frame_offset) {
  return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset));
}


int RegExpMacroAssemblerMIPS::CheckStackGuardState(Address* return_address,
                                                  Code* re_code,
                                                  Address re_frame) {
  UNIMPLEMENTED_MIPS();
  return 0;
}


MemOperand RegExpMacroAssemblerMIPS::register_location(int register_index) {
  UNIMPLEMENTED_MIPS();
  return MemOperand(zero_reg, 0);
}


void RegExpMacroAssemblerMIPS::CheckPosition(int cp_offset,
                                            Label* on_outside_input) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::BranchOrBacktrack(Label* to,
                                                 Condition condition,
                                                 Register rs,
                                                 const Operand& rt) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::SafeCall(Label* to, Condition cond, Register rs,
                                           const Operand& rt) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::SafeReturn() {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::SafeCallTarget(Label* name) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::Push(Register source) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::Pop(Register target) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::CheckPreemption() {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::CheckStackLimit() {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::CallCFunctionUsingStub(
    ExternalReference function,
    int num_arguments) {
  UNIMPLEMENTED_MIPS();
}


void RegExpMacroAssemblerMIPS::LoadCurrentCharacterUnchecked(int cp_offset,
                                                             int characters) {
  UNIMPLEMENTED_MIPS();
}


void RegExpCEntryStub::Generate(MacroAssembler* masm_) {
  UNIMPLEMENTED_MIPS();
}


#undef __

#endif  // V8_INTERPRETED_REGEXP

}}  // namespace v8::internal

#endif  // V8_TARGET_ARCH_MIPS