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++) {
......
This diff is collapsed.
......@@ -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