Commit 02698516 authored by lrn@chromium.org's avatar lrn@chromium.org

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


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@873 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 2c2ae533
......@@ -840,6 +840,26 @@ void Assembler::and_(const Operand& dst, Register src) {
}
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 @@ void Assembler::rep_cmpsb() {
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
}
......
......@@ -189,6 +189,9 @@ class Immediate BASE_EMBEDDED {
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 @@ class Assembler : public Malloced {
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);
......
......@@ -513,12 +513,12 @@ Handle<Object> RegExpImpl::IrregexpExecOnce(Handle<JSRegExp> regexp,
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++) {
......
......@@ -51,6 +51,7 @@ namespace v8 { namespace internal {
*
* 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 @@ namespace v8 { namespace internal {
* - 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 @@ namespace v8 { namespace internal {
* 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 @@ void RegExpMacroAssemblerIA32::CheckBitmap(uc16 start,
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::CheckBitmap(uc16 start,
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 @@ void RegExpMacroAssemblerIA32::CheckCharacters(Vector<const uc16> str,
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 @@ void RegExpMacroAssemblerIA32::CheckCharacters(Vector<const uc16> str,
__ 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::CheckCurrentPosition(int register_index,
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 @@ void RegExpMacroAssemblerIA32::CheckNotBackReference(
__ 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 @@ void RegExpMacroAssemblerIA32::CheckNotRegistersEqual(int reg1,
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::CheckNotCharacter(uc16 c, Label* on_not_equal) {
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 @@ void RegExpMacroAssemblerIA32::CheckNotCharacterAfterMinusOr(
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 @@ void RegExpMacroAssemblerIA32::DispatchHalfNibbleMap(
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 @@ void RegExpMacroAssemblerIA32::DispatchByteMap(
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 @@ void RegExpMacroAssemblerIA32::DispatchHighByteMap(
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::DispatchHighByteMap(
void RegExpMacroAssemblerIA32::EmitOrLink(Label* label) {
UNREACHABLE(); // Has no use.
UNIMPLEMENTED(); // Has no use.
}
......@@ -395,9 +434,19 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode() {
__ 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 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode() {
}
__ mov(eax, Immediate(1));
// Exit and return eax
__ bind(&exit_label_);
__ leave();
__ pop(ebx);
......@@ -439,7 +489,6 @@ void RegExpMacroAssemblerIA32::GoTo(Label* to) {
}
void RegExpMacroAssemblerIA32::IfRegisterGE(int reg,
int comparand,
Label* if_ge) {
......@@ -448,7 +497,6 @@ void RegExpMacroAssemblerIA32::IfRegisterGE(int reg,
}
void RegExpMacroAssemblerIA32::IfRegisterLT(int reg,
int comparand,
Label* if_lt) {
......@@ -457,21 +505,19 @@ void RegExpMacroAssemblerIA32::IfRegisterLT(int reg,
}
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::PopCurrentPosition() {
void RegExpMacroAssemblerIA32::PopRegister(int register_index) {
RecordRegister(register_index);
__ pop(register_location(register_index));
}
......@@ -514,7 +559,6 @@ void RegExpMacroAssemblerIA32::ReadStackPointerFromRegister(int reg) {
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::Succeed() {
}
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 @@ void RegExpMacroAssemblerIA32::WriteStackPointerToRegister(int reg) {
// 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::BranchOrBacktrack(Condition condition,
}
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::CheckStackLimit() {
}
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)));
}
......
......@@ -88,6 +88,19 @@ class RegExpMacroAssemblerIA32: public RegExpMacroAssembler {
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 @@ class RegExpMacroAssemblerIA32: public RegExpMacroAssembler {
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,32 +125,25 @@ class RegExpMacroAssemblerIA32: public RegExpMacroAssembler {
// 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).
void CheckStackLimit();
......
......@@ -183,6 +183,7 @@ void RegExpMacroAssemblerTracer::CheckCharacter(uc16 c, Label* on_equal) {
void RegExpMacroAssemblerTracer::CheckNotAtStart(Label* on_not_at_start) {
PrintF(" CheckNotAtStart(label[%08x]);\n", on_not_at_start);
assembler_->CheckNotAtStart(on_not_at_start);
}
......
......@@ -582,9 +582,6 @@ TEST(MacroAssembler) {
#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 @@ TEST(MacroAssemblerIA32Success) {
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 @@ TEST(MacroAssemblerIA32Success) {
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(MacroAssemblerIA32Success) {
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 @@ TEST(MacroAssemblerIA32Simple) {
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 @@ TEST(MacroAssemblerIA32Simple) {
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 @@ TEST(MacroAssemblerIA32Simple) {
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 @@ TEST(MacroAssemblerIA32SimpleUC16) {
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 @@ TEST(MacroAssemblerIA32SimpleUC16) {
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 @@ TEST(MacroAssemblerIA32SimpleUC16) {
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 @@ TEST(MacroAssemblerIA32Backtrack) {
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 @@ TEST(MacroAssemblerIA32Backtrack) {
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 @@ TEST(MacroAssemblerIA32Registers) {
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 @@ TEST(MacroAssemblerIA32Registers) {
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]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment