Author: [EMAIL PROTECTED]
Date: Mon Dec  1 01:57:14 2008
New Revision: 873

Modified:
    branches/bleeding_edge/src/assembler-ia32.cc
    branches/bleeding_edge/src/assembler-ia32.h
    branches/bleeding_edge/src/jsregexp.cc
    branches/bleeding_edge/src/regexp-macro-assembler-ia32.cc
    branches/bleeding_edge/src/regexp-macro-assembler-ia32.h
    branches/bleeding_edge/src/regexp-macro-assembler-tracer.cc
    branches/bleeding_edge/test/cctest/test-regexp.cc

Log:
Fixes (last?) bugs in regexp-ia32 core functionality. All tests run!


Modified: branches/bleeding_edge/src/assembler-ia32.cc
==============================================================================
--- branches/bleeding_edge/src/assembler-ia32.cc        (original)
+++ branches/bleeding_edge/src/assembler-ia32.cc        Mon Dec  1 01:57:14 2008
@@ -840,6 +840,26 @@
  }


+void Assembler::cmpb(const Operand& op, int8_t imm8) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  EMIT(0x80);
+  emit_operand(edi, op);  // edi == 7
+  EMIT(imm8);
+}
+
+
+void Assembler::cmpw(const Operand& op, Immediate imm16) {
+  ASSERT(imm16.is_int16());
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  EMIT(0x66);
+  EMIT(0x81);
+  emit_operand(edi, op);
+  emit_w(imm16);
+}
+
+
  void Assembler::cmp(Register reg, int32_t imm32) {
    EnsureSpace ensure_space(this);
    last_pc_ = pc_;
@@ -877,12 +897,13 @@
    EMIT(0xA6);  // CMPSB
  }

-void Assembler::rep_cmpsl() {
+void Assembler::rep_cmpsw() {
    EnsureSpace ensure_space(this);
    last_pc_ = pc_;
    EMIT(0xFC);  // CLD to ensure forward operation
    EMIT(0xF3);  // REP
-  EMIT(0xA7);  // CMPSW
+  EMIT(0x66);  // Operand size overide.
+  EMIT(0xA7);  // CMPS
  }



Modified: branches/bleeding_edge/src/assembler-ia32.h
==============================================================================
--- branches/bleeding_edge/src/assembler-ia32.h (original)
+++ branches/bleeding_edge/src/assembler-ia32.h Mon Dec  1 01:57:14 2008
@@ -189,6 +189,9 @@
    bool is_int8() const {
      return -128 <= x_ && x_ < 128 && rmode_ == RelocInfo::NONE;
    }
+  bool is_int16() const {
+    return -32768 <= x_ && x_ < 32768 && rmode_ == RelocInfo::NONE;
+  }

   private:
    int x_;
@@ -493,13 +496,15 @@
    void and_(const Operand& src, Register dst);
    void and_(const Operand& dst, const Immediate& x);

+  void cmpb(const Operand& op, int8_t imm8);
+  void cmpw(const Operand& op, Immediate imm16);
    void cmp(Register reg, int32_t imm32);
    void cmp(Register reg, Handle<Object> handle);
    void cmp(Register reg, const Operand& op);
    void cmp(const Operand& op, const Immediate& imm);

    void rep_cmpsb();
-  void rep_cmpsl();
+  void rep_cmpsw();

    void dec_b(Register dst);


Modified: branches/bleeding_edge/src/jsregexp.cc
==============================================================================
--- branches/bleeding_edge/src/jsregexp.cc      (original)
+++ branches/bleeding_edge/src/jsregexp.cc      Mon Dec  1 01:57:14 2008
@@ -513,12 +513,12 @@
        int start_offset = string_offset + previous_index * sizeof(uc16);
        int end_offset =
            string_offset + two_byte_subject->length() * sizeof(uc16);
-      typedef bool testfunc(String**, int, int, int*);
-      testfunc* test = FUNCTION_CAST<testfunc*>(code->entry());
-      rc = test(two_byte_subject.location(),
-                start_offset,
-                end_offset,
-                offsets_vector);
+      rc = RegExpMacroAssemblerIA32::Execute(code,
+                                             two_byte_subject.location(),
+                                             start_offset,
+                                             end_offset,
+                                             offsets_vector,
+                                             previous_index == 0);
        if (rc) {
          // Capture values are relative to start_offset only.
          for (int i = 0; i < offsets_vector_length; i++) {

Modified: branches/bleeding_edge/src/regexp-macro-assembler-ia32.cc
==============================================================================
--- branches/bleeding_edge/src/regexp-macro-assembler-ia32.cc   (original)
+++ branches/bleeding_edge/src/regexp-macro-assembler-ia32.cc   Mon Dec  1  
01:57:14 2008
@@ -51,6 +51,7 @@
   *
   * Each call to a public method should retain this convention.
   * The stack will have the following structure:
+ *       - at_start           (if 1, start at start of string, if 0, don't)
   *       - int* capture_array (int[num_saved_registers_], for output).
   *       - end of input       (index of end of string, relative to  
*string_base)
   *       - start of input     (index of first character in string, relative
@@ -59,6 +60,7 @@
   *       - return address
   *       - backup of esi
   *       - backup of edi
+ *       - backup of ebx
   * ebp-> - old ebp
   *       - register 0  ebp[-4]  (Only positions must be stored in the first
   *       - register 1  ebp[-8]   num_saved_registers_ registers)
@@ -73,7 +75,8 @@
   * bool (*match)(String** string_base,
   *               int start_offset,
   *               int end_offset,
- *               int* capture_output_array)
+ *               int* capture_output_array,
+ *               bool at_start)
   */

  #define __ masm_->
@@ -135,7 +138,7 @@
                                             Label* bitmap,
                                             Label* on_zero) {
    UNREACHABLE();
-  ReadCurrentChar(eax);
+  __ mov(eax, current_character());
    __ sub(Operand(eax), Immediate(start));
    __ cmp(eax, 64);  // FIXME: 64 = length_of_bitmap_in_bits.
    BranchOrBacktrack(greater_equal, on_zero);
@@ -151,24 +154,29 @@


  void RegExpMacroAssemblerIA32::CheckCharacter(uc16 c, Label* on_equal) {
-  __ cmp(edx, c);
+  __ cmp(current_character(), c);
    BranchOrBacktrack(equal, on_equal);
  }


  void RegExpMacroAssemblerIA32::CheckCharacterGT(uc16 limit, Label*  
on_greater) {
-  __ cmp(edx, limit);
+  __ cmp(current_character(), limit);
    BranchOrBacktrack(greater, on_greater);
  }


  void RegExpMacroAssemblerIA32::CheckNotAtStart(Label* on_not_at_start) {
-  UNIMPLEMENTED();
+  __ cmp(Operand(ebp, kAtStart), Immediate(0));
+  BranchOrBacktrack(equal, on_not_at_start);
+  __ mov(eax, Operand(ebp, kInputEndOffset));
+  __ add(eax, Operand(edi));
+  __ cmp(eax, Operand(ebp, kInputStartOffset));
+  BranchOrBacktrack(not_equal, on_not_at_start);
  }


  void RegExpMacroAssemblerIA32::CheckCharacterLT(uc16 limit, Label*  
on_less) {
-  __ cmp(edx, limit);
+  __ cmp(current_character(), limit);
    BranchOrBacktrack(less, on_less);
  }

@@ -178,9 +186,23 @@
                                                 Label* on_failure) {
    int byte_length = str.length() * char_size();
    int byte_offset = cp_offset * char_size();
-  __ mov(ebx, edi);
-  __ add(Operand(ebx), Immediate(byte_offset + byte_length));
-  BranchOrBacktrack(greater_equal, on_failure);
+  __ cmp(Operand(edi), Immediate(-(byte_offset + byte_length)));
+  BranchOrBacktrack(greater, on_failure);
+
+  if (str.length() <= kMaxInlineStringTests) {
+    for (int i = 0; i < str.length(); i++) {
+      if (mode_ == ASCII) {
+        __ cmpb(Operand(esi, edi, times_1, byte_offset + i),
+                static_cast<int8_t>(str[i]));
+      } else {
+        ASSERT(mode_ == UC16);
+        __ cmpw(Operand(esi, edi, times_1, byte_offset + i * sizeof(uc16)),
+                Immediate(str[i]));
+      }
+      __ j(not_equal, on_failure);
+    }
+    return;
+  }

    ArraySlice constant_buffer = constants_.GetBuffer(str.length(),  
char_size());
    if (mode_ == ASCII) {
@@ -197,8 +219,13 @@
    __ mov(ebx, esi);
    __ lea(edi, Operand(esi, edi, times_1, byte_offset));
    LoadConstantBufferAddress(esi, &constant_buffer);
-  __ mov(ecx, str.length() * char_size());
-  __ rep_cmpsb();
+  __ mov(ecx, str.length());
+  if (char_size() == 1) {
+    __ rep_cmpsb();
+  } else {
+    ASSERT(char_size() == 2);
+    __ rep_cmpsw();
+  }
    __ mov(esi, ebx);
    __ mov(edi, eax);
    BranchOrBacktrack(not_equal, on_failure);
@@ -214,7 +241,16 @@

  void RegExpMacroAssemblerIA32::CheckNotBackReferenceIgnoreCase(
      int start_reg, Label* on_no_match) {
-  UNIMPLEMENTED();
+  Label fallthrough;
+  __ mov(eax, register_location(start_reg));
+  __ mov(ecx, register_location(start_reg + 1));
+  __ sub(ecx, Operand(eax));  // Length to check.
+  __ j(less, on_no_match);
+  __ j(equal, &fallthrough);
+
+  UNIMPLEMENTED();  // TODO(lrn): Call runtime function to do test.
+
+  __ bind(&fallthrough);
  }


@@ -224,15 +260,16 @@
    __ mov(eax, register_location(start_reg));
    __ mov(ecx, register_location(start_reg + 1));
    __ sub(ecx, Operand(eax));  // Length to check.
-  __ j(equal, &fallthrough);  // Covers the case where it's not bound  
(-1,-1).
+  __ j(less, on_no_match);
+  __ j(equal, &fallthrough);
+  // check that there are sufficient characters left in the input
+  __ mov(ebx, edi);
+  __ add(ebx, Operand(ecx));
+  __ j(greater, on_no_match);
    __ mov(ebx, Operand(edi));
    __ push(esi);
    __ add(edi, Operand(esi));
    __ add(esi, Operand(eax));
-  if (char_size() > 0) {
-    ASSERT(char_size() == 2);
-    __ add(ecx, Operand(ecx));
-  }
    __ rep_cmpsb();
    __ pop(esi);
    __ mov(edi, Operand(ebx));
@@ -245,14 +282,13 @@
                                                        int reg2,
                                                        Label* on_not_equal)  
{
    __ mov(eax, register_location(reg1));
-  __ mov(ecx, register_location(reg2));
-  __ cmp(ecx, Operand(eax));
+  __ cmp(eax, register_location(reg2));
    BranchOrBacktrack(not_equal, on_not_equal);
  }


  void RegExpMacroAssemblerIA32::CheckNotCharacter(uc16 c, Label*  
on_not_equal) {
-  __ cmp(edx, c);
+  __ cmp(current_character(), c);
    BranchOrBacktrack(not_equal, on_not_equal);
  }

@@ -260,7 +296,7 @@
  void RegExpMacroAssemblerIA32::CheckNotCharacterAfterOr(uc16 c,
                                                          uc16 mask,
                                                          Label*  
on_not_equal) {
-  __ mov(eax, Operand(edx));
+  __ mov(eax, current_character());
    __ or_(eax, mask);
    __ cmp(eax, c);
    BranchOrBacktrack(not_equal, on_not_equal);
@@ -271,7 +307,7 @@
      uc16 c,
      uc16 mask,
      Label* on_not_equal) {
-  __ lea(eax, Operand(edx, -mask));
+  __ lea(eax, Operand(current_character(), -mask));
    __ or_(eax, mask);
    __ cmp(eax, c);
    BranchOrBacktrack(not_equal, on_not_equal);
@@ -282,7 +318,8 @@
      uc16 start,
      Label* half_nibble_map,
      const Vector<Label*>& destinations) {
-  ReadCurrentChar(eax);
+  UNIMPLEMENTED();
+  __ mov(eax, current_character());
    __ sub(Operand(eax), Immediate(start));

    __ mov(ecx, eax);
@@ -318,8 +355,10 @@
      uc16 start,
      Label* byte_map,
      const Vector<Label*>& destinations) {
+  UNIMPLEMENTED();
+
    Label fallthrough;
-  ReadCurrentChar(eax);
+  __ mov(eax, current_character());
    __ sub(Operand(eax), Immediate(start));
    __ cmp(eax, 64);  // FIXME: 64 = size of map. Found somehow??
    __ j(greater_equal, &fallthrough);
@@ -335,10 +374,10 @@
      byte start,
      Label* byte_map,
      const Vector<Label*>& destinations) {
-  UNREACHABLE();
+  UNIMPLEMENTED();

    Label fallthrough;
-  ReadCurrentChar(eax);
+  __ mov(eax, current_character());
    __ shr(eax, 8);
    __ sub(Operand(eax), Immediate(start));
    __ cmp(eax, destinations.length() - start);
@@ -350,7 +389,7 @@


  void RegExpMacroAssemblerIA32::EmitOrLink(Label* label) {
-  UNREACHABLE();  // Has no use.
+  UNIMPLEMENTED();  // Has no use.
  }


@@ -395,9 +434,19 @@
      __ inc(ecx);
      __ j(not_equal, &init_loop);
    }
+  // Load previous char as initial value of current-character.
+  Label at_start;
+  __ cmp(Operand(ebp, kAtStart), Immediate(0));
+  __ j(not_equal, &at_start);
+  LoadCurrentCharToRegister(-1);  // Load previous char.
+  __ jmp(&start_label_);
+  __ bind(&at_start);
+  __ mov(current_character(), '\n');
    __ jmp(&start_label_);

+
    // Exit code:
+  // Success
    __ bind(&success_label_);
    if (num_saved_registers_ > 0) {
      // copy captures to output
@@ -416,6 +465,7 @@
    }
    __ mov(eax, Immediate(1));

+  // Exit and return eax
    __ bind(&exit_label_);
    __ leave();
    __ pop(ebx);
@@ -439,7 +489,6 @@
  }


-
  void RegExpMacroAssemblerIA32::IfRegisterGE(int reg,
                                              int comparand,
                                              Label* if_ge) {
@@ -448,7 +497,6 @@
  }


-
  void RegExpMacroAssemblerIA32::IfRegisterLT(int reg,
                                              int comparand,
                                              Label* if_lt) {
@@ -457,21 +505,19 @@
  }


-
  RegExpMacroAssembler::IrregexpImplementation
      RegExpMacroAssemblerIA32::Implementation() {
    return kIA32Implementation;
  }


-
  void RegExpMacroAssemblerIA32::LoadCurrentCharacter(int cp_offset,
                                                      Label*  
on_end_of_input) {
    ASSERT(cp_offset >= 0);
    ASSERT(cp_offset < (1<<30));  // Be sane! (And ensure negation works)
    __ cmp(edi, -cp_offset * char_size());
    BranchOrBacktrack(greater_equal, on_end_of_input);
-  ReadChar(edx, cp_offset);
+  LoadCurrentCharToRegister(cp_offset);
  }


@@ -481,7 +527,6 @@


  void RegExpMacroAssemblerIA32::PopRegister(int register_index) {
-  RecordRegister(register_index);
    __ pop(register_location(register_index));
  }

@@ -514,7 +559,6 @@

  void RegExpMacroAssemblerIA32::SetRegister(int register_index, int to) {
    ASSERT(register_index >= num_saved_registers_);  // Reserved for  
positions!
-  RecordRegister(register_index);
    __ mov(register_location(register_index), Immediate(to));
  }

@@ -524,10 +568,8 @@
  }


-void RegExpMacroAssemblerIA32::WriteCurrentPositionToRegister(
-    int register_index) {
-  RecordRegister(register_index);
-  __ mov(register_location(register_index), edi);
+void RegExpMacroAssemblerIA32::WriteCurrentPositionToRegister(int reg) {
+  __ mov(register_location(reg), edi);
  }

  void RegExpMacroAssemblerIA32::WriteStackPointerToRegister(int reg) {
@@ -537,13 +579,20 @@

  // Private methods:

-Operand RegExpMacroAssemblerIA32::register_location(
-    int register_index) {
+Operand RegExpMacroAssemblerIA32::register_location(int register_index) {
    ASSERT(register_index < (1<<30));
+  if (num_registers_ <= register_index) {
+    num_registers_ = register_index + 1;
+  }
    return Operand(ebp, -(register_index + 1) * kPointerSize);
  }


+Register RegExpMacroAssemblerIA32::current_character() {
+  return edx;
+}
+
+
  size_t RegExpMacroAssemblerIA32::char_size() {
    return static_cast<size_t>(mode_);
  }
@@ -570,22 +619,6 @@
  }


-void RegExpMacroAssemblerIA32::Canonicalize(Register reg) {
-  if (mode_ == ASCII) {
-    Label end;
-    __ cmp(Operand(reg), Immediate('a'));
-    __ j(below, &end);
-    __ cmp(Operand(reg), Immediate('z'));
-    __ j(above, &end);
-    __ sub(Operand(reg), Immediate('a' - 'A'));
-    __ bind(&end);
-    return;
-  }
-  ASSERT(mode_ == UC16);
-  // TODO(lrn): Use some tables.
-}
-
-
  void RegExpMacroAssemblerIA32::CheckStackLimit() {
    if (FLAG_check_stack) {
      // Check for preemption first.
@@ -624,25 +657,14 @@
  }


-void RegExpMacroAssemblerIA32::RecordRegister(int register_index) {
-  if (register_index >= num_registers_) {
-    num_registers_ = register_index + 1;
-  }
-}
-
-
-void RegExpMacroAssemblerIA32::ReadChar(Register destination, int offset) {
+void RegExpMacroAssemblerIA32::LoadCurrentCharToRegister(int cp_offset) {
    if (mode_ == ASCII) {
-    __ movzx_b(destination, Operand(esi, edi, times_1, offset));
+    __ movzx_b(current_character(), Operand(esi, edi, times_1, cp_offset));
      return;
    }
    ASSERT(mode_ == UC16);
-  __ movzx_w(destination, Operand(esi, edi, times_1, offset * 2));
-}
-
-
-void RegExpMacroAssemblerIA32::ReadCurrentChar(Register destination) {
-  __ mov(destination, edx);
+  __ movzx_w(current_character(),
+             Operand(esi, edi, times_1, cp_offset * sizeof(uc16)));
  }



Modified: branches/bleeding_edge/src/regexp-macro-assembler-ia32.h
==============================================================================
--- branches/bleeding_edge/src/regexp-macro-assembler-ia32.h    (original)
+++ branches/bleeding_edge/src/regexp-macro-assembler-ia32.h    Mon Dec  1  
01:57:14 2008
@@ -88,6 +88,19 @@
    virtual void WriteCurrentPositionToRegister(int reg);
    virtual void WriteStackPointerToRegister(int reg);

+  template <typename T>
+  static inline bool Execute(Code* code,
+                             T** input,
+                             int start_offset,
+                             int end_offset,
+                             int* output,
+                             bool at_start) {
+    typedef bool (*matcher)(T**, int, int, int*, int);
+    matcher matcher_func = FUNCTION_CAST<matcher>(code->entry());
+    int at_start_val = at_start ? 1 : 0;
+    return matcher_func(input, start_offset, end_offset, output,  
at_start_val);
+  }
+
   private:
    // Offsets from ebp of arguments to function.
    static const int kBackup_ebx = sizeof(uint32_t);
@@ -98,6 +111,7 @@
    static const int kInputStartOffset = kInputBuffer + sizeof(uint32_t);
    static const int kInputEndOffset = kInputStartOffset + sizeof(uint32_t);
    static const int kRegisterOutput = kInputEndOffset + sizeof(uint32_t);
+  static const int kAtStart = kRegisterOutput + sizeof(uint32_t);

    // Initial size of code buffer.
    static const size_t kRegExpCodeSize = 1024;
@@ -111,31 +125,24 @@
    // The ebp-relative location of a regexp register.
    Operand register_location(int register_index);

+  // The register containing the current character after  
LoadCurrentCharacter.
+  Register current_character();
+
    // Byte size of chars in the string to match (decided by the Mode  
argument)
    size_t char_size();

-  // Records that a register is used. At the end, we need the number of
-  // registers used.
-  void RecordRegister(int register_index);
-
    // Equivalent to a conditional branch to the label, unless the label
    // is NULL, in which case it is a conditional Backtrack.
    void BranchOrBacktrack(Condition condition, Label* to);

-  // Generate code to perform case-canonicalization on the register.
-  void Canonicalize(Register register);
-
    // Read a character from input at the given offset from the current
    // position.
-  void ReadChar(Register destination, int offset);
+  void LoadCurrentCharToRegister(int cp_offset);

    // Load the address of a "constant buffer" (a slice of a byte array)
    // into a register. The address is computed from the ByteArray* address
    // and an offset. Uses no extra registers.
    void LoadConstantBufferAddress(Register reg, ArraySlice* buffer);
-
-  // Read the current character into the destination register.
-  void ReadCurrentChar(Register destination);

    // Adds code that checks whether preemption has been requested
    // (and checks if we have hit the stack limit too).

Modified: branches/bleeding_edge/src/regexp-macro-assembler-tracer.cc
==============================================================================
--- branches/bleeding_edge/src/regexp-macro-assembler-tracer.cc (original)
+++ branches/bleeding_edge/src/regexp-macro-assembler-tracer.cc Mon Dec  1  
01:57:14 2008
@@ -183,6 +183,7 @@

  void RegExpMacroAssemblerTracer::CheckNotAtStart(Label* on_not_at_start) {
    PrintF(" CheckNotAtStart(label[%08x]);\n", on_not_at_start);
+  assembler_->CheckNotAtStart(on_not_at_start);
  }



Modified: branches/bleeding_edge/test/cctest/test-regexp.cc
==============================================================================
--- branches/bleeding_edge/test/cctest/test-regexp.cc   (original)
+++ branches/bleeding_edge/test/cctest/test-regexp.cc   Mon Dec  1 01:57:14  
2008
@@ -582,9 +582,6 @@
  #ifndef ARM  // IA32 only tests.

  TEST(MacroAssemblerIA32Success) {
-  typedef bool (*AsciiTest) (
-      SeqAsciiString** base, int start_index, int end_index, int*  
captures);
-
    V8::Initialize(NULL);

    // regexp-macro-assembler-ia32 needs a handle scope to allocate
@@ -597,7 +594,6 @@

    Handle<Object> code_object = m.GetCode();
    Handle<Code> code = Handle<Code>::cast(code_object);
-  AsciiTest test = FUNCTION_CAST<AsciiTest>(code->entry());

    int captures[4] = {42, 37, 87, 117};
    Handle<String> input = Factory::NewStringFromAscii(CStrVector("foofoo"));
@@ -606,8 +602,12 @@
    int start_offset = start_adr - reinterpret_cast<Address>(*seq_input);
    int end_offset = start_offset + seq_input->length();

-  bool success =
-      test(seq_input.location(), start_offset, end_offset, captures);
+  bool success = RegExpMacroAssemblerIA32::Execute(*code,
+                                                   seq_input.location(),
+                                                   start_offset,
+                                                   end_offset,
+                                                   captures,
+                                                   true);

    CHECK(success);
    CHECK_EQ(-1, captures[0]);
@@ -618,9 +618,6 @@


  TEST(MacroAssemblerIA32Simple) {
-  typedef bool (*AsciiTest) (
-      SeqAsciiString** base, int start_index, int end_index, int*  
captures);
-
    V8::Initialize(NULL);

    // regexp-macro-assembler-ia32 needs a handle scope to allocate
@@ -643,7 +640,6 @@

    Handle<Object> code_object = m.GetCode();
    Handle<Code> code = Handle<Code>::cast(code_object);
-  AsciiTest test = FUNCTION_CAST<AsciiTest>(code->entry());

    int captures[4] = {42, 37, 87, 117};
    Handle<String> input = Factory::NewStringFromAscii(CStrVector("foofoo"));
@@ -652,8 +648,12 @@
    int start_offset = start_adr - reinterpret_cast<Address>(*seq_input);
    int end_offset = start_offset + seq_input->length();

-  bool success =
-      test(seq_input.location(), start_offset, end_offset, captures);
+  bool success = RegExpMacroAssemblerIA32::Execute(*code,
+                                                   seq_input.location(),
+                                                   start_offset,
+                                                   end_offset,
+                                                   captures,
+                                                   true);

    CHECK(success);
    CHECK_EQ(0, captures[0]);
@@ -667,16 +667,18 @@
    start_offset = start_adr - reinterpret_cast<Address>(*seq_input);
    end_offset = start_offset + seq_input->length();

-  success = test(seq_input.location(), start_offset, end_offset, captures);
+  success = RegExpMacroAssemblerIA32::Execute(*code,
+                                              seq_input.location(),
+                                              start_offset,
+                                              end_offset,
+                                              captures,
+                                              true);

    CHECK(!success);
  }


  TEST(MacroAssemblerIA32SimpleUC16) {
-  typedef bool (*UC16Test) (
-      SeqTwoByteString** base, int start_index, int end_index, int*  
captures);
-
    V8::Initialize(NULL);

    // regexp-macro-assembler-ia32 needs a handle scope to allocate
@@ -699,7 +701,6 @@

    Handle<Object> code_object = m.GetCode();
    Handle<Code> code = Handle<Code>::cast(code_object);
-  UC16Test test = FUNCTION_CAST<UC16Test>(code->entry());

    int captures[4] = {42, 37, 87, 117};
    const uc16 input_data[6] = {'f', 'o', 'o', 'f', 'o', '\xa0'};
@@ -710,8 +711,12 @@
    int start_offset = start_adr - reinterpret_cast<Address>(*seq_input);
    int end_offset = start_offset + seq_input->length() * sizeof(uc16);

-  bool success =
-      test(seq_input.location(), start_offset, end_offset, captures);
+  bool success = RegExpMacroAssemblerIA32::Execute(*code,
+                                                   seq_input.location(),
+                                                   start_offset,
+                                                   end_offset,
+                                                   captures,
+                                                   true);

    CHECK(success);
    CHECK_EQ(0, captures[0]);
@@ -726,16 +731,18 @@
    start_offset = start_adr - reinterpret_cast<Address>(*seq_input);
    end_offset = start_offset + seq_input->length() * sizeof(uc16);

-  success = test(seq_input.location(), start_offset, end_offset, captures);
+  success = RegExpMacroAssemblerIA32::Execute(*code,
+                                              seq_input.location(),
+                                              start_offset,
+                                              end_offset,
+                                              captures,
+                                              true);

    CHECK(!success);
  }


  TEST(MacroAssemblerIA32Backtrack) {
-  typedef bool (*AsciiTest) (
-      SeqAsciiString** base, int start_index, int end_index, int*  
captures);
-
    V8::Initialize(NULL);

    // regexp-macro-assembler-ia32 needs a handle scope to allocate
@@ -760,7 +767,6 @@

    Handle<Object> code_object = m.GetCode();
    Handle<Code> code = Handle<Code>::cast(code_object);
-  AsciiTest test = FUNCTION_CAST<AsciiTest>(code->entry());

    Handle<String> input = Factory::NewStringFromAscii(CStrVector("foofoo"));
    Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input);
@@ -768,17 +774,81 @@
    int start_offset = start_adr - reinterpret_cast<Address>(*seq_input);
    int end_offset = start_offset + seq_input->length();

-  bool success =
-      test(seq_input.location(), start_offset, end_offset, NULL);
+  bool success = RegExpMacroAssemblerIA32::Execute(*code,
+                                                   seq_input.location(),
+                                                   start_offset,
+                                                   end_offset,
+                                                   NULL,
+                                                   true);

    CHECK(!success);
  }

+TEST(MacroAssemblerIA32AtStart) {
+  V8::Initialize(NULL);
+
+  // regexp-macro-assembler-ia32 needs a handle scope to allocate
+  // byte-arrays for constants.
+  v8::HandleScope scope;

-TEST(MacroAssemblerIA32Registers) {
-  typedef bool (*AsciiTest) (
-      SeqAsciiString** base, int start_index, int end_index, int*  
captures);
+  RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 0);
+
+  uc16 foo_chars[3] = {'f', 'o', 'o'};
+  Vector<const uc16> foo(foo_chars, 3);
+
+  Label not_at_start, newline, fail;
+  m.CheckNotAtStart(&not_at_start);
+  // Check that prevchar = '\n' and current = 'f'.
+  m.CheckCharacter('\n', &newline);
+  m.Bind(&fail);
+  m.Fail();
+  m.Bind(&newline);
+  m.LoadCurrentCharacter(0, &fail);
+  m.CheckNotCharacter('f', &fail);
+  m.Succeed();

+  m.Bind(&not_at_start);
+  // Check that prevchar = 'o' and current = 'b'.
+  Label prevo;
+  m.CheckCharacter('o', &prevo);
+  m.Fail();
+  m.Bind(&prevo);
+  m.LoadCurrentCharacter(0, &fail);
+  m.CheckNotCharacter('b', &fail);
+  m.Succeed();
+
+  Handle<Object> code_object = m.GetCode();
+  Handle<Code> code = Handle<Code>::cast(code_object);
+
+  Handle<String> input = Factory::NewStringFromAscii(CStrVector("foobar"));
+  Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input);
+  Address start_adr = seq_input->GetCharsAddress();
+  int start_offset = start_adr - reinterpret_cast<Address>(*seq_input);
+  int end_offset = start_offset + seq_input->length();
+
+  bool success = RegExpMacroAssemblerIA32::Execute(*code,
+                                                   seq_input.location(),
+                                                   start_offset,
+                                                   end_offset,
+                                                   NULL,
+                                                   true);
+
+  CHECK(success);
+
+  start_offset += 3;
+  success = RegExpMacroAssemblerIA32::Execute(*code,
+                                              seq_input.location(),
+                                              start_offset,
+                                              end_offset,
+                                              NULL,
+                                              false);
+
+  CHECK(success);
+}
+
+
+
+TEST(MacroAssemblerIA32Registers) {
    V8::Initialize(NULL);

    // regexp-macro-assembler-ia32 needs a handle scope to allocate
@@ -850,7 +920,6 @@

    Handle<Object> code_object = m.GetCode();
    Handle<Code> code = Handle<Code>::cast(code_object);
-  AsciiTest test = FUNCTION_CAST<AsciiTest>(code->entry());

    // String long enough for test (content doesn't matter).
    Handle<String> input =
@@ -861,8 +930,12 @@
    int end_offset = start_offset + seq_input->length();

    int output[5];
-  bool success =
-      test(seq_input.location(), start_offset, end_offset, output);
+  bool success = RegExpMacroAssemblerIA32::Execute(*code,
+                                                   seq_input.location(),
+                                                   start_offset,
+                                                   end_offset,
+                                                   output,
+                                                   true);

    CHECK(success);
    CHECK_EQ(0, output[0]);

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to