Commit 4722a886 authored by erik.corry@gmail.com's avatar erik.corry@gmail.com

Implement $ for non-multiline.

Review URL: http://codereview.chromium.org/10992

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@862 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 2b72eeed
......@@ -247,6 +247,16 @@ void IrregexpAssembler::CheckNotBackReferenceNoCase(int capture_index,
}
void IrregexpAssembler::CheckNotRegistersEqual(int reg1,
int reg2,
Label* on_not_equal) {
Emit(BC_CHECK_NOT_REGS_EQUAL);
Emit(reg1);
Emit(reg2);
EmitOrLink(on_not_equal);
}
void IrregexpAssembler::CheckRegister(int byte_code,
int reg_index,
uint16_t vs,
......
......@@ -103,6 +103,7 @@ class IrregexpAssembler {
// on_mismatch label will never be called.
void CheckNotBackReference(int capture_index, Label* on_mismatch);
void CheckNotBackReferenceNoCase(int capture_index, Label* on_mismatch);
void CheckNotRegistersEqual(int reg1, int reg2, Label* on_not_equal);
// Checks a register for strictly-less-than or greater-than-or-equal.
void CheckRegisterLT(int reg_index, uint16_t vs, Label* on_less_than);
......
......@@ -58,12 +58,13 @@ V(CHECK_LT, 22, 7) /* check_lt uc16 addr32 */ \
V(CHECK_GT, 23, 7) /* check_gr uc16 addr32 */ \
V(CHECK_NOT_BACK_REF, 24, 6) /* check_not_back_ref capture_idx addr32 */ \
V(CHECK_NOT_BACK_REF_NO_CASE, 25, 6) /* check_not_back_ref_no_case captu... */ \
V(LOOKUP_MAP1, 26, 11) /* l_map1 start16 bit_map_addr32 addr32 */ \
V(LOOKUP_MAP2, 27, 99) /* l_map2 start16 half_nibble_map_addr32* */ \
V(LOOKUP_MAP8, 28, 99) /* l_map8 start16 byte_map addr32* */ \
V(LOOKUP_HI_MAP8, 29, 99) /* l_himap8 start8 byte_map_addr32 addr32* */ \
V(CHECK_REGISTER_LT, 30, 8) /* check_reg_lt register_index value16 addr32 */ \
V(CHECK_REGISTER_GE, 31, 8) /* check_reg_ge register_index value16 addr32 */
V(CHECK_NOT_REGS_EQUAL, 26, 7) /* check_not_regs_equal reg1 reg2 addr32 */ \
V(LOOKUP_MAP1, 27, 11) /* l_map1 start16 bit_map_addr32 addr32 */ \
V(LOOKUP_MAP2, 28, 99) /* l_map2 start16 half_nibble_map_addr32* */ \
V(LOOKUP_MAP8, 29, 99) /* l_map8 start16 byte_map addr32* */ \
V(LOOKUP_HI_MAP8, 30, 99) /* l_himap8 start8 byte_map_addr32 addr32* */ \
V(CHECK_REGISTER_LT, 31, 8) /* check_reg_lt register_index value16 addr32 */ \
V(CHECK_REGISTER_GE, 32, 8) /* check_reg_ge register_index value16 addr32 */
#define DECLARE_BYTECODES(name, code, length) \
static const int BC_##name = code;
......
......@@ -204,6 +204,7 @@ DEFINE_bool(irregexp, false, "new regular expression code")
DEFINE_bool(trace_regexps, false, "trace Irregexp execution")
DEFINE_bool(irregexp_native, false, "use native code Irregexp implementation (IA32 only)")
DEFINE_bool(disable_jscre, false, "abort if JSCRE is used. Only useful with --irregexp")
DEFINE_bool(attempt_multiline_irregexp, false, "attempt to use Irregexp for multiline regexps")
// Testing flags test/cctest/test-{flags,api,serialization}.cc
DEFINE_bool(testing_bool_flag, true, "testing_bool_flag")
......
......@@ -323,6 +323,13 @@ static bool RawMatch(const byte* code_base,
pc = code_base + Load32(new_pc);
break;
}
BYTECODE(CHECK_NOT_REGS_EQUAL)
if (registers[pc[1]] == registers[pc[2]]) {
pc += BC_CHECK_NOT_REGS_EQUAL_LENGTH;
} else {
pc = code_base + Load32(pc + 3);
}
break;
BYTECODE(CHECK_NOT_BACK_REF) {
int from = registers[pc[1]];
int len = registers[pc[1] + 1] - from;
......
This diff is collapsed.
......@@ -576,7 +576,6 @@ class ActionNode: public SeqRegExpNode {
STORE_REGISTER,
INCREMENT_REGISTER,
STORE_POSITION,
SAVE_POSITION,
RESTORE_POSITION,
BEGIN_SUBMATCH,
ESCAPE_SUBMATCH
......@@ -584,10 +583,14 @@ class ActionNode: public SeqRegExpNode {
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(int reg, RegExpNode* on_success);
static ActionNode* EscapeSubmatch(int reg, RegExpNode* on_success);
static ActionNode* BeginSubmatch(int stack_pointer_reg,
int position_reg,
RegExpNode* on_success);
static ActionNode* EscapeSubmatch(int stack_pointer_reg,
bool and_restore_position,
int restore_reg,
RegExpNode* on_success);
virtual void Accept(NodeVisitor* visitor);
virtual bool Emit(RegExpCompiler* compiler);
virtual RegExpNode* PropagateForward(NodeInfo* info);
......@@ -604,8 +607,9 @@ class ActionNode: public SeqRegExpNode {
int reg;
} u_position_register;
struct {
int reg;
} u_submatch_stack_pointer_register;
int stack_pointer_register;
int current_position_register;
} u_submatch;
} data_;
ActionNode(Type type, RegExpNode* on_success)
: SeqRegExpNode(on_success),
......
......@@ -236,6 +236,16 @@ void RegExpMacroAssemblerIA32::CheckNotBackReference(
}
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));
BranchOrBacktrack(not_equal, on_not_equal);
}
void RegExpMacroAssemblerIA32::CheckNotCharacter(uc16 c, Label* on_not_equal) {
__ cmp(edx, c);
BranchOrBacktrack(not_equal, on_not_equal);
......
......@@ -52,6 +52,7 @@ class RegExpMacroAssemblerIA32: public RegExpMacroAssembler {
virtual void CheckNotBackReference(int start_reg, Label* on_no_match);
virtual void CheckNotBackReferenceIgnoreCase(int start_reg,
Label* on_no_match);
virtual void CheckNotRegistersEqual(int reg1, int reg2, Label* on_not_equal);
virtual void CheckNotCharacter(uc16 c, Label* on_not_equal);
virtual void CheckNotCharacterAfterOr(uc16 c, uc16 mask, Label* on_not_equal);
virtual void CheckNotCharacterAfterMinusOr(uc16 c,
......
......@@ -206,6 +206,13 @@ void RegExpMacroAssemblerIrregexp::CheckNotBackReferenceIgnoreCase(
}
void RegExpMacroAssemblerIrregexp::CheckNotRegistersEqual(int reg1,
int reg2,
Label* on_not_equal) {
assembler_->CheckNotRegistersEqual(reg1, reg2, on_not_equal);
}
void RegExpMacroAssemblerIrregexp::CheckBitmap(uc16 start,
Label* bitmap,
Label* on_zero) {
......
......@@ -67,6 +67,7 @@ class RegExpMacroAssemblerIrregexp: public RegExpMacroAssembler {
virtual void CheckNotBackReference(int start_reg, Label* on_no_match);
virtual void CheckNotBackReferenceIgnoreCase(int start_reg,
Label* on_no_match);
virtual void CheckNotRegistersEqual(int reg1, int reg2, Label* on_not_equal);
virtual void CheckCharacters(Vector<const uc16> str,
int cp_offset,
Label* on_failure);
......
......@@ -194,6 +194,18 @@ void RegExpMacroAssemblerTracer::CheckNotBackReferenceIgnoreCase(
assembler_->CheckNotBackReferenceIgnoreCase(start_reg, on_no_match);
}
void RegExpMacroAssemblerTracer::CheckNotRegistersEqual(int reg1,
int reg2,
Label* on_not_equal) {
PrintF(" CheckNotRegistersEqual(reg1=%d, reg2=%d, label[%08x]);\n",
reg1,
reg2,
on_not_equal);
assembler_->CheckNotRegistersEqual(reg1, reg2, on_not_equal);
}
void RegExpMacroAssemblerTracer::CheckCharacters(Vector<const uc16> str,
int cp_offset,
Label* on_failure) {
......
......@@ -54,6 +54,7 @@ class RegExpMacroAssemblerTracer: public RegExpMacroAssembler {
virtual void CheckNotBackReference(int start_reg, Label* on_no_match);
virtual void CheckNotBackReferenceIgnoreCase(int start_reg,
Label* on_no_match);
virtual void CheckNotRegistersEqual(int reg1, int reg2, Label* on_not_equal);
virtual void CheckNotCharacter(uc16 c, Label* on_not_equal);
virtual void CheckNotCharacterAfterOr(uc16 c,
uc16 or_with,
......
......@@ -93,6 +93,7 @@ class RegExpMacroAssembler {
virtual void CheckNotCharacterAfterMinusOr(uc16 c,
uc16 minus_then_or_with,
Label* on_not_equal) = 0;
virtual void CheckNotRegistersEqual(int reg1, int reg2, Label* on_not_equal) = 0;
// Dispatch after looking the current character up in a byte map. The
// destinations vector has up to 256 labels.
virtual void DispatchByteMap(
......
......@@ -1226,5 +1226,5 @@ TEST(CharacterRangeCaseIndependence) {
TEST(Graph) {
V8::Initialize(NULL);
Execute("(?:foo|bar$)", false, true);
Execute("foo$(?!bar)", false, true);
}
......@@ -244,3 +244,23 @@ assertEquals("bar$00", "foox".replace(re, "bar$00"), "$00");
assertEquals("bar$000", "foox".replace(re, "bar$000"), "$000");
assertEquals("barx", "foox".replace(re, "bar$01"), "$01 2");
assertEquals("barx5", "foox".replace(re, "bar$15"), "$15");
assertFalse(/()foo$\1/.test("football"), "football1");
assertFalse(/foo$(?=ball)/.test("football"), "football2");
assertFalse(/foo$(?!bar)/.test("football"), "football3");
assertTrue(/()foo$\1/.test("foo"), "football4");
assertTrue(/foo$(?=(ball)?)/.test("foo"), "football5");
assertTrue(/()foo$(?!bar)/.test("foo"), "football6");
assertFalse(/(x?)foo$\1/.test("football"), "football7");
assertFalse(/foo$(?=ball)/.test("football"), "football8");
assertFalse(/foo$(?!bar)/.test("football"), "football9");
assertTrue(/(x?)foo$\1/.test("foo"), "football10");
assertTrue(/foo$(?=(ball)?)/.test("foo"), "football11");
assertTrue(/foo$(?!bar)/.test("foo"), "football12");
// Check that the back reference has two successors. See
// BackReferenceNode::PropagateForward.
assertFalse(/f(o)\b\1/.test('foo'));
assertTrue(/f(o)\B\1/.test('foo'));
assertFalse(/f(o)$\1/.test('foo'), "backref detects at_end");
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