Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(137)

Unified Diff: src/regexp-macro-assembler-ia32.cc

Issue 12944: * Implemented case-insensitive back-reference matching in irregexp-ia32. (Closed)
Patch Set: Review comments addressed Created 12 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/regexp-macro-assembler-ia32.h ('k') | test/cctest/test-regexp.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/regexp-macro-assembler-ia32.cc
diff --git a/src/regexp-macro-assembler-ia32.cc b/src/regexp-macro-assembler-ia32.cc
index 76b4bcff5dd27a6e369c3e623d5710ce74371fd0..b1aaaf5f0e954b6ac7069882859c6de3bd73b14e 100644
--- a/src/regexp-macro-assembler-ia32.cc
+++ b/src/regexp-macro-assembler-ia32.cc
@@ -27,6 +27,7 @@
#include <string.h>
#include "v8.h"
+#include "unicode.h"
#include "log.h"
#include "ast.h"
#include "macro-assembler.h"
@@ -240,22 +241,97 @@ void RegExpMacroAssemblerIA32::CheckCurrentPosition(int register_index,
void RegExpMacroAssemblerIA32::CheckNotBackReferenceIgnoreCase(
- int start_reg, Label* on_no_match) {
+ int start_reg,
+ Label* on_no_match) {
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);
+ BranchOrBacktrack(less, on_no_match);
__ j(equal, &fallthrough);
- UNIMPLEMENTED(); // TODO(lrn): Call runtime function to do test.
+ if (mode_ == ASCII) {
+ Label success;
+ Label fail;
+ __ push(esi);
+ __ push(edi);
+ __ add(edi, Operand(esi));
+ __ add(esi, Operand(eax));
+ Label loop;
+ __ bind(&loop);
+ __ rep_cmpsb();
+ __ j(equal, &success);
+ // Compare lower-case if letters.
+ __ movzx_b(eax, Operand(edi, -1));
+ __ or_(eax, 0x20); // To-lower-case
+ __ lea(ebx, Operand(eax, -'a'));
+ __ cmp(ebx, static_cast<int32_t>('z' - 'a'));
+ __ j(above, &fail);
+ __ movzx_b(ebx, Operand(esi, -1));
+ __ or_(ebx, 0x20); // To-lower-case
+ __ cmp(eax, Operand(ebx));
+ __ j(not_equal, &fail);
+ __ or_(ecx, Operand(ecx));
+ __ j(not_equal, &loop);
+ __ jmp(&success);
+
+ __ bind(&fail);
+ __ pop(edi);
+ __ pop(esi);
+ BranchOrBacktrack(no_condition, on_no_match);
+ __ bind(&success);
+ __ pop(eax); // discard original value of edi
+ __ pop(esi);
+ __ sub(edi, Operand(esi));
+ } else {
+ // store state
+ __ push(esi);
+ __ push(edi);
+ __ push(ecx);
+ // align stack
+ int frameAlignment = OS::ActivationFrameAlignment();
+ if (frameAlignment != 0) {
+ __ mov(ebx, esp);
+ __ sub(Operand(esp), Immediate(5 * kPointerSize)); // args + esp.
+ ASSERT(IsPowerOf2(frameAlignment));
+ __ and_(esp, -frameAlignment);
+ __ mov(Operand(esp, 4 * kPointerSize), ebx);
+ } else {
+ __ sub(Operand(esp), Immediate(4 * kPointerSize));
+ }
+ // Put arguments on stack.
+ __ mov(Operand(esp, 3 * kPointerSize), ecx);
+ __ mov(ebx, Operand(ebp, kInputEndOffset));
+ __ add(edi, Operand(ebx));
+ __ mov(Operand(esp, 2 * kPointerSize), edi);
+ __ add(eax, Operand(ebx));
+ __ mov(Operand(esp, 1 * kPointerSize), eax);
+ __ mov(eax, Operand(ebp, kInputBuffer));
+ __ mov(Operand(esp, 0 * kPointerSize), eax);
+ Address function_address = FUNCTION_ADDR(&CaseInsensitiveCompareUC16);
+ __ mov(Operand(eax),
+ Immediate(reinterpret_cast<int32_t>(function_address)));
+ __ call(Operand(eax));
+ if (frameAlignment != 0) {
+ __ mov(esp, Operand(esp, 4 * kPointerSize));
+ } else {
+ __ add(Operand(esp), Immediate(4 * sizeof(int32_t)));
+ }
+ __ pop(ecx);
+ __ pop(edi);
+ __ pop(esi);
+ __ or_(eax, Operand(eax));
+ BranchOrBacktrack(zero, on_no_match);
+ __ add(edi, Operand(ecx));
+ }
__ bind(&fallthrough);
}
void RegExpMacroAssemblerIA32::CheckNotBackReference(
- int start_reg, Label* on_no_match) {
+ int start_reg,
+ Label* on_no_match) {
Label fallthrough;
__ mov(eax, register_location(start_reg));
__ mov(ecx, register_location(start_reg + 1));
@@ -586,6 +662,37 @@ void RegExpMacroAssemblerIA32::WriteStackPointerToRegister(int reg) {
// Private methods:
+
+static unibrow::Mapping<unibrow::Ecma262Canonicalize> canonicalize;
+
+
+int RegExpMacroAssemblerIA32::CaseInsensitiveCompareUC16(uc16** buffer,
+ int byte_offset1,
+ int byte_offset2,
+ size_t byte_length) {
+ ASSERT(byte_length % 2 == 0);
+ Address buffer_address = reinterpret_cast<Address>(*buffer);
+ uc16* substring1 = reinterpret_cast<uc16*>(buffer_address + byte_offset1);
+ uc16* substring2 = reinterpret_cast<uc16*>(buffer_address + byte_offset2);
+ size_t length = byte_length >> 1;
+
+ for (size_t i = 0; i < length; i++) {
+ unibrow::uchar c1 = substring1[i];
+ unibrow::uchar c2 = substring2[i];
+ if (c1 != c2) {
+ canonicalize.get(c1, '\0', &c1);
+ if (c1 != c2) {
+ canonicalize.get(c2, '\0', &c2);
+ if (c1 != c2) {
+ return 0;
+ }
+ }
+ }
+ }
+ return 1;
+}
+
+
Operand RegExpMacroAssemblerIA32::register_location(int register_index) {
ASSERT(register_index < (1<<30));
if (num_registers_ <= register_index) {
« no previous file with comments | « src/regexp-macro-assembler-ia32.h ('k') | test/cctest/test-regexp.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698