Author: [EMAIL PROTECTED]
Date: Thu Nov 20 03:28:33 2008
New Revision: 804
Modified:
branches/experimental/regexp2000/src/assembler-re2k.cc
branches/experimental/regexp2000/src/assembler-re2k.h
branches/experimental/regexp2000/src/bytecodes-re2k.h
branches/experimental/regexp2000/src/interpreter-re2k.cc
branches/experimental/regexp2000/src/jsregexp.cc
branches/experimental/regexp2000/src/jsregexp.h
branches/experimental/regexp2000/src/regexp-macro-assembler-re2k.cc
branches/experimental/regexp2000/src/regexp-macro-assembler-re2k.h
branches/experimental/regexp2000/src/regexp-macro-assembler.h
branches/experimental/regexp2000/test/cctest/test-regexp.cc
branches/experimental/regexp2000/test/mozilla/mozilla.status
Log:
* Add support for positive lookahead assertions and negative
lookahead assertions.
* Fix sense of CheckChar and CheckNotChar to match CheckCharLT
in bytecode assembler. Also rename them from Char to Character.
* Mark unexpected pass in Mozilla tests (we can cope with 500
parentheses).
* Mark unexpected hang in Mozilla tests (exponential regexp,
JSCRE bails out).
* Support negative character classes (yes, the parser still
generates them).
Review URL: http://codereview.chromium.org/11319
Modified: branches/experimental/regexp2000/src/assembler-re2k.cc
==============================================================================
--- branches/experimental/regexp2000/src/assembler-re2k.cc (original)
+++ branches/experimental/regexp2000/src/assembler-re2k.cc Thu Nov 20
03:28:33 2008
@@ -73,7 +73,7 @@
}
-void Re2kAssembler::SetRegisterToCurrentPosition(int index, int cp_offset)
{
+void Re2kAssembler::WriteCurrentPositionToRegister(int index, int
cp_offset) {
ASSERT(cp_offset >= 0);
ASSERT(index >= 0);
Emit(BC_SET_REGISTER_TO_CP);
@@ -82,6 +82,27 @@
}
+void Re2kAssembler::ReadCurrentPositionFromRegister(int index) {
+ ASSERT(index >= 0);
+ Emit(BC_SET_CP_TO_REGISTER);
+ Emit(index);
+}
+
+
+void Re2kAssembler::WriteStackPointerToRegister(int index) {
+ ASSERT(index >= 0);
+ Emit(BC_SET_REGISTER_TO_SP);
+ Emit(index);
+}
+
+
+void Re2kAssembler::ReadStackPointerFromRegister(int index) {
+ ASSERT(index >= 0);
+ Emit(BC_SET_SP_TO_REGISTER);
+ Emit(index);
+}
+
+
void Re2kAssembler::SetRegister(int index, int value) {
ASSERT(index >= 0);
Emit(BC_SET_REGISTER);
@@ -162,17 +183,17 @@
}
-void Re2kAssembler::CheckChar(uc16 c, Label* on_mismatch) {
+void Re2kAssembler::CheckCharacter(uc16 c, Label* on_match) {
Emit(BC_CHECK_CHAR);
Emit16(c);
- EmitOrLink(on_mismatch);
+ EmitOrLink(on_match);
}
-void Re2kAssembler::CheckNotChar(uc16 c, Label* on_match) {
+void Re2kAssembler::CheckNotCharacter(uc16 c, Label* on_mismatch) {
Emit(BC_CHECK_NOT_CHAR);
Emit16(c);
- EmitOrLink(on_match);
+ EmitOrLink(on_mismatch);
}
Modified: branches/experimental/regexp2000/src/assembler-re2k.h
==============================================================================
--- branches/experimental/regexp2000/src/assembler-re2k.h (original)
+++ branches/experimental/regexp2000/src/assembler-re2k.h Thu Nov 20
03:28:33 2008
@@ -33,7 +33,10 @@
void PushCurrentPosition(int cp_offset = 0);
void PushBacktrack(Label* l);
void PushRegister(int index);
- void SetRegisterToCurrentPosition(int index, int cp_offset = 0);
+ void WriteCurrentPositionToRegister(int index, int cp_offset = 0);
+ void ReadCurrentPositionFromRegister(int index);
+ void WriteStackPointerToRegister(int index);
+ void ReadStackPointerFromRegister(int index);
void SetRegister(int index, int value);
void AdvanceRegister(int index, int by);
@@ -57,8 +60,8 @@
void LoadCurrentChar(int cp_offset, Label* on_end);
// Checks current char register against a singleton.
- void CheckChar(uc16 c, Label* on_mismatch);
- void CheckNotChar(uc16 c, Label* on_match);
+ void CheckCharacter(uc16 c, Label* on_match);
+ void CheckNotCharacter(uc16 c, Label* on_mismatch);
// Used to check current char register against a range.
void CheckCharacterLT(uc16 limit, Label* on_less);
Modified: branches/experimental/regexp2000/src/bytecodes-re2k.h
==============================================================================
--- branches/experimental/regexp2000/src/bytecodes-re2k.h (original)
+++ branches/experimental/regexp2000/src/bytecodes-re2k.h Thu Nov 20
03:28:33 2008
@@ -37,28 +37,31 @@
V(PUSH_BT, 2, 5) /* push_bt
addr32 */ \
V(PUSH_REGISTER, 3, 2) /* push_register
register_index */ \
V(SET_REGISTER_TO_CP, 4, 6) /* set_register_to_cp register_index
offset32 */ \
-V(SET_REGISTER, 5, 6) /* set_register register_index
value32 */ \
-V(ADVANCE_REGISTER, 6, 6) /* advance_register register_index
value32 */ \
-V(POP_CP, 7, 1) /*
pop_cp */ \
-V(POP_BT, 8, 1) /*
pop_bt */ \
-V(POP_REGISTER, 9, 2) /* pop_register
register_index */ \
-V(FAIL, 10, 1) /*
fail */ \
-V(SUCCEED, 11, 1) /*
succeed */ \
-V(ADVANCE_CP, 12, 5) /* advance_cp
offset32 */ \
-V(GOTO, 13, 5) /* goto
addr32 */ \
-V(LOAD_CURRENT_CHAR, 14, 9) /* load offset32
addr32 */ \
-V(CHECK_CHAR, 15, 7) /* check_char uc16
addr32 */ \
-V(CHECK_NOT_CHAR, 16, 7) /* check_not_char uc16
addr32 */ \
-V(CHECK_LT, 17, 7) /* check_lt uc16
addr32 */ \
-V(CHECK_GT, 18, 7) /* check_gr uc16
addr32 */ \
-V(CHECK_BACKREF, 19, 9) /* check_backref offset32 capture_idx
addr32 */ \
-V(CHECK_NOT_BACKREF, 20, 9) /* check_not_backref offset32 capture_idx
addr32*/ \
-V(LOOKUP_MAP1, 21, 11) /* l_map1 start16 bit_map_addr32
addr32 */ \
-V(LOOKUP_MAP2, 22, 99) /* l_map2 start16
half_nibble_map_addr32* */ \
-V(LOOKUP_MAP8, 23, 99) /* l_map8 start16 byte_map
addr32* */ \
-V(LOOKUP_HI_MAP8, 24, 99) /* l_himap8 start8 byte_map_addr32
addr32* */ \
-V(CHECK_REGISTER_LT, 25, 8) /* check_reg_lt register_index value16
addr32 */ \
-V(CHECK_REGISTER_GE, 26, 8) /* check_reg_ge register_index value16
addr32 */ \
+V(SET_CP_TO_REGISTER, 5, 2) /* set_cp_to_registger
register_index */ \
+V(SET_REGISTER_TO_SP, 6, 2) /* set_register_to_sp
register_index */ \
+V(SET_SP_TO_REGISTER, 7, 2) /* set_sp_to_registger
register_index */ \
+V(SET_REGISTER, 8, 6) /* set_register register_index
value32 */ \
+V(ADVANCE_REGISTER, 9, 6) /* advance_register register_index
value32 */ \
+V(POP_CP, 10, 1) /*
pop_cp */ \
+V(POP_BT, 11, 1) /*
pop_bt */ \
+V(POP_REGISTER, 12, 2) /* pop_register
register_index */ \
+V(FAIL, 13, 1) /*
fail */ \
+V(SUCCEED, 14, 1) /*
succeed */ \
+V(ADVANCE_CP, 15, 5) /* advance_cp
offset32 */ \
+V(GOTO, 16, 5) /* goto
addr32 */ \
+V(LOAD_CURRENT_CHAR, 17, 9) /* load offset32
addr32 */ \
+V(CHECK_CHAR, 18, 7) /* check_char uc16
addr32 */ \
+V(CHECK_NOT_CHAR, 19, 7) /* check_not_char uc16
addr32 */ \
+V(CHECK_LT, 20, 7) /* check_lt uc16
addr32 */ \
+V(CHECK_GT, 21, 7) /* check_gr uc16
addr32 */ \
+V(CHECK_BACKREF, 22, 9) /* check_backref offset32 capture_idx
addr32 */ \
+V(CHECK_NOT_BACKREF, 23, 9) /* check_not_backref offset32 capture_idx
addr32*/ \
+V(LOOKUP_MAP1, 24, 11) /* l_map1 start16 bit_map_addr32
addr32 */ \
+V(LOOKUP_MAP2, 25, 99) /* l_map2 start16
half_nibble_map_addr32* */ \
+V(LOOKUP_MAP8, 26, 99) /* l_map8 start16 byte_map
addr32* */ \
+V(LOOKUP_HI_MAP8, 27, 99) /* l_himap8 start8 byte_map_addr32
addr32* */ \
+V(CHECK_REGISTER_LT, 28, 8) /* check_reg_lt register_index value16
addr32 */ \
+V(CHECK_REGISTER_GE, 29, 8) /* check_reg_ge register_index value16
addr32 */ \
#define DECLARE_BYTECODES(name, code, length) \
static const int BC_##name = code;
Modified: branches/experimental/regexp2000/src/interpreter-re2k.cc
==============================================================================
--- branches/experimental/regexp2000/src/interpreter-re2k.cc (original)
+++ branches/experimental/regexp2000/src/interpreter-re2k.cc Thu Nov 20
03:28:33 2008
@@ -77,8 +77,9 @@
int* registers,
int current) {
const byte* pc = code_base;
- int backtrack_stack[10000];
- int backtrack_stack_space = 10000;
+ static const int kBacktrackStackSize = 10000;
+ int backtrack_stack[kBacktrackStackSize];
+ int backtrack_stack_space = kBacktrackStackSize;
int* backtrack_sp = backtrack_stack;
int current_char = -1;
#ifdef DEBUG
@@ -124,6 +125,20 @@
registers[pc[1]] = current + Load32(pc + 2);
pc += BC_SET_REGISTER_TO_CP_LENGTH;
break;
+ BYTECODE(SET_CP_TO_REGISTER)
+ current = registers[pc[1]];
+ pc += BC_SET_CP_TO_REGISTER_LENGTH;
+ break;
+ BYTECODE(SET_REGISTER_TO_SP)
+ registers[pc[1]] = backtrack_sp - backtrack_stack;
+ pc += BC_SET_REGISTER_TO_SP_LENGTH;
+ break;
+ BYTECODE(SET_SP_TO_REGISTER)
+ backtrack_sp = backtrack_stack + registers[pc[1]];
+ backtrack_stack_space = kBacktrackStackSize -
+ (backtrack_sp - backtrack_stack);
+ pc += BC_SET_SP_TO_REGISTER_LENGTH;
+ break;
BYTECODE(POP_CP)
backtrack_stack_space++;
--backtrack_sp;
@@ -164,7 +179,7 @@
}
BYTECODE(CHECK_CHAR) {
int c = Load16(pc + 1);
- if (c != current_char) {
+ if (c == current_char) {
pc = code_base + Load32(pc + 3);
} else {
pc += BC_CHECK_CHAR_LENGTH;
@@ -173,7 +188,7 @@
}
BYTECODE(CHECK_NOT_CHAR) {
int c = Load16(pc + 1);
- if (c == current_char) {
+ if (c != current_char) {
pc = code_base + Load32(pc + 3);
} else {
pc += BC_CHECK_NOT_CHAR_LENGTH;
Modified: branches/experimental/regexp2000/src/jsregexp.cc
==============================================================================
--- branches/experimental/regexp2000/src/jsregexp.cc (original)
+++ branches/experimental/regexp2000/src/jsregexp.cc Thu Nov 20 03:28:33
2008
@@ -1012,25 +1012,31 @@
}
-ActionNode* ActionNode::RestorePosition(int reg, RegExpNode* on_success) {
- ActionNode* result = new ActionNode(RESTORE_POSITION, on_success);
+ActionNode* ActionNode::SavePosition(int reg, RegExpNode* on_success) {
+ ActionNode* result = new ActionNode(SAVE_POSITION, on_success);
result->data_.u_position_register.reg = reg;
return result;
}
-ActionNode* ActionNode::BeginSubmatch(RegExpNode* on_success) {
- return new ActionNode(BEGIN_SUBMATCH, on_success);
+ActionNode* ActionNode::RestorePosition(int reg, RegExpNode* on_success) {
+ ActionNode* result = new ActionNode(RESTORE_POSITION, on_success);
+ result->data_.u_position_register.reg = reg;
+ return result;
}
-ActionNode* ActionNode::EscapeSubmatch(RegExpNode* on_success) {
- return new ActionNode(ESCAPE_SUBMATCH, on_success);
+ActionNode* ActionNode::BeginSubmatch(int reg, RegExpNode* on_success) {
+ ActionNode* result = new ActionNode(BEGIN_SUBMATCH, on_success);
+ result->data_.u_submatch_stack_pointer_register.reg = reg;
+ return result;
}
-ActionNode* ActionNode::EndSubmatch(RegExpNode* on_success) {
- return new ActionNode(END_SUBMATCH, on_success);
+ActionNode* ActionNode::EscapeSubmatch(int reg, RegExpNode* on_success) {
+ ActionNode* result = new ActionNode(ESCAPE_SUBMATCH, on_success);
+ result->data_.u_submatch_stack_pointer_register.reg = reg;
+ return result;
}
@@ -1078,18 +1084,22 @@
}
case TextElement::CHAR_CLASS: {
RegExpCharacterClass* cc = elm.data.u_char_class;
- if (cc->is_negated()) return false;
macro_assembler->LoadCurrentCharacter(cp_offset,
on_failure_->label());
cp_offset++;
ZoneList<CharacterRange>* ranges = cc->ranges();
- Label found;
+ Label success;
+
+ Label *char_is_in_class =
+ cc->is_negated() ? on_failure_->label() : &success;
int range_count = ranges->length();
if (range_count == 0) {
- on_failure()->GoTo(compiler);
+ if (!cc->is_negated()) {
+ on_failure()->GoTo(compiler);
+ }
break;
}
@@ -1098,29 +1108,58 @@
Label next_range;
uc16 from = range.from();
uc16 to = range.to();
- if (from != 0) {
- macro_assembler->CheckCharacterLT(from, &next_range);
- }
- if (to != 0xffff) {
- macro_assembler->CheckCharacterLT(to + 1, &found);
+ if (to == from) {
+ macro_assembler->CheckCharacter(to, char_is_in_class);
} else {
- macro_assembler->AdvanceCurrentPosition(1);
- on_success()->GoTo(compiler);
+ if (from != 0) {
+ macro_assembler->CheckCharacterLT(from, &next_range);
+ }
+ if (to != 0xffff) {
+ macro_assembler->CheckCharacterLT(to + 1, char_is_in_class);
+ } else {
+ macro_assembler->GoTo(char_is_in_class);
+ }
}
macro_assembler->Bind(&next_range);
}
- CharacterRange& range = (*ranges)[range_count - 1];
- uc16 from = range.from();
- uc16 to = range.to();
- if (from != 0) {
- macro_assembler->CheckCharacterLT(from, on_failure_->label());
- }
- if (to != 0xffff) {
- macro_assembler->CheckCharacterGT(to, on_failure_->label());
+ if (range_count != 0) {
+ CharacterRange& range = (*ranges)[range_count - 1];
+ uc16 from = range.from();
+ uc16 to = range.to();
+
+ if (to == from) {
+ if (cc->is_negated()) {
+ macro_assembler->CheckCharacter(to, on_failure_->label());
+ } else {
+ macro_assembler->CheckNotCharacter(to, on_failure_->label());
+ }
+ } else {
+ if (from != 0) {
+ if (!cc->is_negated()) {
+ macro_assembler->CheckCharacterLT(from,
on_failure_->label());
+ } else {
+ macro_assembler->CheckCharacterLT(from, &success);
+ }
+ }
+ if (to != 0xffff) {
+ if (!cc->is_negated()) {
+ macro_assembler->CheckCharacterGT(to,
on_failure_->label());
+ } else {
+ macro_assembler->CheckCharacterLT(to + 1,
on_failure_->label());
+ }
+ } else {
+ if (cc->is_negated()) {
+ macro_assembler->GoTo(on_failure_->label());
+ }
+ }
+ }
+ } else if (cc->is_negated()) {
+ macro_assembler->GoTo(on_failure_->label());
}
- compiler->AddWork(on_failure_);
- macro_assembler->Bind(&found);
+
+ macro_assembler->Bind(&success);
+
break;
}
default:
@@ -1128,6 +1167,7 @@
return false;
}
}
+ compiler->AddWork(on_failure_);
macro_assembler->AdvanceCurrentPosition(cp_offset);
return on_success()->GoTo(compiler);
}
@@ -1172,11 +1212,11 @@
}
if (!on_failure_->IsBacktrack()) {
macro_assembler->PushBacktrack(on_failure_->label());
+ compiler->AddWork(on_failure_);
}
if (!alternative.node()->GoTo(compiler)) {
return false;
}
- compiler->AddWork(on_failure_);
return true;
}
@@ -1218,18 +1258,22 @@
macro->Backtrack();
break;
}
+ case SAVE_POSITION:
+ macro->WriteCurrentPositionToRegister(
+ data_.u_position_register.reg);
+ break;
case RESTORE_POSITION:
- // TODO(erikcorry): Implement this.
- return false;
+ macro->ReadCurrentPositionFromRegister(
+ data_.u_position_register.reg);
+ break;
case BEGIN_SUBMATCH:
- // TODO(erikcorry): Implement this.
- return false;
+ macro->WriteStackPointerToRegister(
+ data_.u_submatch_stack_pointer_register.reg);
+ break;
case ESCAPE_SUBMATCH:
- // TODO(erikcorry): Implement this.
- return false;
- case END_SUBMATCH:
- // TODO(erikcorry): Implement this.
- return false;
+ macro->ReadStackPointerFromRegister(
+ data_.u_submatch_stack_pointer_register.reg);
+ break;
default:
UNREACHABLE();
return false;
@@ -1433,6 +1477,10 @@
stream()->Add("label=\"$%i:=$pos\", shape=octagon",
that->data_.u_position_register.reg);
break;
+ case ActionNode::SAVE_POSITION:
+ stream()->Add("label=\"$%i:=$pos\", shape=octagon",
+ that->data_.u_position_register.reg);
+ break;
case ActionNode::RESTORE_POSITION:
stream()->Add("label=\"$pos:=$%i\", shape=octagon",
that->data_.u_position_register.reg);
@@ -1443,9 +1491,6 @@
case ActionNode::ESCAPE_SUBMATCH:
stream()->Add("label=\"escape\", shape=septagon");
break;
- case ActionNode::END_SUBMATCH:
- stream()->Add("label=\"end\", shape=septagon");
- break;
}
stream()->Add("];\n");
stream()->Add(" n%p -> n%p;\n", that, that->on_success());
@@ -1653,8 +1698,9 @@
RegExpNode* RegExpLookahead::ToNode(RegExpCompiler* compiler,
RegExpNode* on_success,
RegExpNode* on_failure) {
+ int stack_pointer_register = compiler->AllocateRegister();
+ int position_register = compiler->AllocateRegister();
if (is_positive()) {
- int position_register = compiler->AllocateRegister();
// begin submatch scope
// $reg = $pos
// if [body]
@@ -1665,11 +1711,17 @@
// else
// end submatch scope (nothing to clean up, just exit the scope)
// fail
- return ActionNode::BeginSubmatch(ActionNode::StorePosition(
- position_register, body()->ToNode(compiler,
- ActionNode::RestorePosition(position_register,
- ActionNode::EscapeSubmatch(on_success)),
- ActionNode::EndSubmatch(on_failure))));
+ return ActionNode::BeginSubmatch(
+ stack_pointer_register,
+ ActionNode::SavePosition(
+ position_register,
+ body()->ToNode(
+ compiler,
+ ActionNode::RestorePosition(
+ position_register,
+ ActionNode::EscapeSubmatch(stack_pointer_register,
+ on_success)),
+ on_failure)));
} else {
// begin submatch scope
// try
@@ -1681,15 +1733,21 @@
// backtrack
// second
// end submatch scope
+ // restore current position
// succeed
ChoiceNode* try_node =
- new ChoiceNode(1, ActionNode::EndSubmatch(on_success));
- RegExpNode* body_node = body()->ToNode(compiler,
- ActionNode::EscapeSubmatch(on_failure),
+ new ChoiceNode(1, ActionNode::RestorePosition(position_register,
+ on_success));
+ RegExpNode* body_node = body()->ToNode(
+ compiler,
+ ActionNode::EscapeSubmatch(stack_pointer_register, on_failure),
compiler->backtrack());
GuardedAlternative body_alt(body_node);
try_node->AddAlternative(body_alt);
- return ActionNode::BeginSubmatch(try_node);
+ return ActionNode::BeginSubmatch(stack_pointer_register,
+ ActionNode::SavePosition(
+ position_register,
+ try_node));
}
}
Modified: branches/experimental/regexp2000/src/jsregexp.h
==============================================================================
--- branches/experimental/regexp2000/src/jsregexp.h (original)
+++ branches/experimental/regexp2000/src/jsregexp.h Thu Nov 20 03:28:33 2008
@@ -543,18 +543,18 @@
STORE_REGISTER,
INCREMENT_REGISTER,
STORE_POSITION,
+ SAVE_POSITION,
RESTORE_POSITION,
BEGIN_SUBMATCH,
- ESCAPE_SUBMATCH,
- END_SUBMATCH
+ ESCAPE_SUBMATCH
};
static ActionNode* StoreRegister(int reg, int val, RegExpNode*
on_success);
static ActionNode* IncrementRegister(int reg, RegExpNode* on_success);
static ActionNode* StorePosition(int reg, RegExpNode* on_success);
+ static ActionNode* SavePosition(int reg, RegExpNode* on_success);
static ActionNode* RestorePosition(int reg, RegExpNode* on_success);
- static ActionNode* BeginSubmatch(RegExpNode* on_success);
- static ActionNode* EscapeSubmatch(RegExpNode* on_success);
- static ActionNode* EndSubmatch(RegExpNode* on_success);
+ static ActionNode* BeginSubmatch(int reg, RegExpNode* on_success);
+ static ActionNode* EscapeSubmatch(int reg, RegExpNode* on_success);
virtual void Accept(NodeVisitor* visitor);
virtual bool Emit(RegExpCompiler* compiler);
virtual RegExpNode* PropagateInterest(NodeInfo* info);
@@ -570,6 +570,9 @@
struct {
int reg;
} u_position_register;
+ struct {
+ int reg;
+ } u_submatch_stack_pointer_register;
} data_;
ActionNode(Type type, RegExpNode* on_success)
: SeqRegExpNode(on_success),
Modified:
branches/experimental/regexp2000/src/regexp-macro-assembler-re2k.cc
==============================================================================
--- branches/experimental/regexp2000/src/regexp-macro-assembler-re2k.cc
(original)
+++ branches/experimental/regexp2000/src/regexp-macro-assembler-re2k.cc Thu
Nov 20 03:28:33 2008
@@ -69,7 +69,24 @@
void RegExpMacroAssemblerRe2k::WriteCurrentPositionToRegister(
int register_index) {
- assembler_->SetRegisterToCurrentPosition(register_index);
+ assembler_->WriteCurrentPositionToRegister(register_index);
+}
+
+
+void RegExpMacroAssemblerRe2k::ReadCurrentPositionFromRegister(
+ int register_index) {
+ assembler_->ReadCurrentPositionFromRegister(register_index);
+}
+
+
+void RegExpMacroAssemblerRe2k::WriteStackPointerToRegister(int
register_index) {
+ assembler_->WriteStackPointerToRegister(register_index);
+}
+
+
+void RegExpMacroAssemblerRe2k::ReadStackPointerFromRegister(
+ int register_index) {
+ assembler_->ReadStackPointerFromRegister(register_index);
}
@@ -137,18 +154,26 @@
}
-void RegExpMacroAssemblerRe2k::CheckCharacterLT(uc16 limit,
- Label* on_less) {
+void RegExpMacroAssemblerRe2k::CheckCharacterLT(uc16 limit, Label*
on_less) {
assembler_->CheckCharacterLT(limit, on_less);
}
-void RegExpMacroAssemblerRe2k::CheckCharacterGT(uc16 limit,
- Label* on_greater) {
+void RegExpMacroAssemblerRe2k::CheckCharacterGT(uc16 limit, Label*
on_greater) {
assembler_->CheckCharacterGT(limit, on_greater);
}
+void RegExpMacroAssemblerRe2k::CheckCharacter(uc16 c, Label* on_equal) {
+ assembler_->CheckCharacter(c, on_equal);
+}
+
+
+void RegExpMacroAssemblerRe2k::CheckNotCharacter(uc16 c, Label*
on_not_equal) {
+ assembler_->CheckNotCharacter(c, on_not_equal);
+}
+
+
void RegExpMacroAssemblerRe2k::CheckBitmap(uc16 start,
Label* bitmap,
Label* on_zero) {
@@ -185,7 +210,7 @@
Label* on_failure) {
for (int i = str.length() - 1; i >= 0; i--) {
assembler_->LoadCurrentChar(cp_offset + i, on_failure);
- assembler_->CheckChar(str[i], on_failure);
+ assembler_->CheckNotCharacter(str[i], on_failure);
}
}
Modified: branches/experimental/regexp2000/src/regexp-macro-assembler-re2k.h
==============================================================================
--- branches/experimental/regexp2000/src/regexp-macro-assembler-re2k.h
(original)
+++ branches/experimental/regexp2000/src/regexp-macro-assembler-re2k.h Thu
Nov 20 03:28:33 2008
@@ -52,9 +52,14 @@
virtual void AdvanceRegister(int reg, int by); // r[reg] += by.
virtual void SetRegister(int register_index, int to);
virtual void WriteCurrentPositionToRegister(int reg);
+ virtual void ReadCurrentPositionFromRegister(int reg);
+ virtual void WriteStackPointerToRegister(int reg);
+ virtual void ReadStackPointerFromRegister(int reg);
virtual void LoadCurrentCharacter(int cp_offset, Label* on_end_of_input);
virtual void CheckCharacterLT(uc16 limit, Label* on_less);
virtual void CheckCharacterGT(uc16 limit, Label* on_greater);
+ virtual void CheckCharacter(uc16 c, Label* on_equal);
+ virtual void CheckNotCharacter(uc16 c, Label* on_not_equal);
virtual void CheckCharacters(Vector<const uc16> str,
int cp_offset,
Label* on_failure);
Modified: branches/experimental/regexp2000/src/regexp-macro-assembler.h
==============================================================================
--- branches/experimental/regexp2000/src/regexp-macro-assembler.h
(original)
+++ branches/experimental/regexp2000/src/regexp-macro-assembler.h Thu Nov
20 03:28:33 2008
@@ -56,9 +56,14 @@
virtual void AdvanceRegister(int reg, int by) = 0; // r[reg] += by.
virtual void SetRegister(int register_index, int to) = 0;
virtual void WriteCurrentPositionToRegister(int reg) = 0;
+ virtual void ReadCurrentPositionFromRegister(int reg) = 0;
+ virtual void WriteStackPointerToRegister(int reg) = 0;
+ virtual void ReadStackPointerFromRegister(int reg) = 0;
virtual void LoadCurrentCharacter(int cp_offset, Label* on_end_of_input)
= 0;
virtual void CheckCharacterLT(uc16 limit, Label* on_less) = 0;
virtual void CheckCharacterGT(uc16 limit, Label* on_greater) = 0;
+ virtual void CheckCharacter(uc16 c, Label* on_equal) = 0;
+ virtual void CheckNotCharacter(uc16 c, Label* on_not_equal) = 0;
// Check the current character for a match with a literal string. If we
// fail to match then goto the on_failure label. End of input always
// matches. If the label is NULL then we should pop a backtrack address
off
Modified: branches/experimental/regexp2000/test/cctest/test-regexp.cc
==============================================================================
--- branches/experimental/regexp2000/test/cctest/test-regexp.cc (original)
+++ branches/experimental/regexp2000/test/cctest/test-regexp.cc Thu Nov 20
03:28:33 2008
@@ -534,13 +534,13 @@
__ AdvanceCP(1);
__ Bind(&look_for_foo);
__ LoadCurrentChar(0, &fail);
- __ CheckChar('f', &advance);
+ __ CheckNotCharacter('f', &advance);
__ LoadCurrentChar(1, &fail);
- __ CheckChar('o', &advance);
+ __ CheckNotCharacter('o', &advance);
__ LoadCurrentChar(2, &fail);
- __ CheckChar('o', &advance);
- __ SetRegisterToCurrentPosition(0);
- __ SetRegisterToCurrentPosition(1, 2);
+ __ CheckNotCharacter('o', &advance);
+ __ WriteCurrentPositionToRegister(0);
+ __ WriteCurrentPositionToRegister(1, 2);
__ Succeed();
__ Bind(&fail);
__ Fail();
@@ -584,7 +584,7 @@
// ^
__ PushCurrentPosition();
__ PushRegister(0);
- __ SetRegisterToCurrentPosition(0);
+ __ WriteCurrentPositionToRegister(0);
__ PushBacktrack(&failure);
__ GoTo(&dot_match);
// .*
@@ -594,15 +594,15 @@
__ PushCurrentPosition();
__ PushBacktrack(&unwind_dot);
__ LoadCurrentChar(0, &foo);
- __ CheckChar('\n', &more_dots);
+ __ CheckNotCharacter('\n', &more_dots);
// foo
__ Bind(&foo);
- __ CheckChar('f', &foo_failed);
+ __ CheckNotCharacter('f', &foo_failed);
__ LoadCurrentChar(1, &foo_failed);
- __ CheckChar('o', &foo_failed);
+ __ CheckNotCharacter('o', &foo_failed);
__ LoadCurrentChar(2, &foo_failed);
- __ CheckChar('o', &foo_failed);
- __ SetRegisterToCurrentPosition(1, 2);
+ __ CheckNotCharacter('o', &foo_failed);
+ __ WriteCurrentPositionToRegister(1, 2);
__ Succeed();
__ Break();
@@ -814,5 +814,5 @@
TEST(Graph) {
V8::Initialize(NULL);
- Execute("(a|^b|c)", "", true);
+ Execute(".*o(?=o)", "", true);
}
Modified: branches/experimental/regexp2000/test/mozilla/mozilla.status
==============================================================================
--- branches/experimental/regexp2000/test/mozilla/mozilla.status
(original)
+++ branches/experimental/regexp2000/test/mozilla/mozilla.status Thu Nov
20
03:28:33 2008
@@ -217,7 +217,7 @@
# depth 500. KJS detects the case, and return null from the match,
# and passes this test (the test doesn't check for a correct return
# value).
-ecma_3/RegExp/regress-119909: FAIL_OK
+ecma_3/RegExp/regress-119909: PASS || FAIL_OK
# Difference in the way capturing subpatterns work. In JS, when the
@@ -234,6 +234,13 @@
# KJS returns true somehow. Maybe they up the match limit? There is
# an open V8 bug 676063 about this.
ecma_3/RegExp/regress-330684: FAIL_OK
+
+
+# This test contains a regexp that runs exponentially long. Spidermonkey
+# standalone will hang, though apparently inside Firefox it will trigger a
+# long-running-script timeout. JSCRE passes by hitting the matchLimit and
+# just pretending that an exhaustive search found no match.
+ecma_3/RegExp/regress-307456: PASS || FAIL_OK
# We do not detect overflow in bounds for back references and {}
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---