Index: src/ia32/regexp-macro-assembler-ia32.cc |
diff --git a/src/ia32/regexp-macro-assembler-ia32.cc b/src/ia32/regexp-macro-assembler-ia32.cc |
index 0029f33b1a36d5d3c3e7d631d2e4e0e92b759297..8238747aa0a083a6e3bbc10e91aa2401f1e141b0 100644 |
--- a/src/ia32/regexp-macro-assembler-ia32.cc |
+++ b/src/ia32/regexp-macro-assembler-ia32.cc |
@@ -1,4 +1,4 @@ |
-// Copyright 2011 the V8 project authors. All rights reserved. |
+// Copyright 2012 the V8 project authors. All rights reserved. |
// Redistribution and use in source and binary forms, with or without |
// modification, are permitted provided that the following conditions are |
// met: |
@@ -706,13 +706,16 @@ bool RegExpMacroAssemblerIA32::CheckSpecialCharacterClass(uc16 type, |
void RegExpMacroAssemblerIA32::Fail() { |
- ASSERT(FAILURE == 0); // Return value for failure is zero. |
- __ Set(eax, Immediate(0)); |
+ STATIC_ASSERT(FAILURE == 0); // Return value for failure is zero. |
+ if (!global()) { |
+ __ Set(eax, Immediate(FAILURE)); |
+ } |
__ jmp(&exit_label_); |
} |
Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) { |
+ Label return_eax, restart; |
// Finalize code - write the entry point code now we know how many |
// registers we need. |
@@ -731,6 +734,7 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) { |
__ push(esi); |
__ push(edi); |
__ push(ebx); // Callee-save on MacOS. |
+ __ push(Immediate(0)); // Number of successful matches in a global regexp. |
__ push(Immediate(0)); // Make room for "input start - 1" constant. |
// Check if we have space on the stack for registers. |
@@ -750,13 +754,13 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) { |
// Exit with OutOfMemory exception. There is not enough space on the stack |
// for our working registers. |
__ mov(eax, EXCEPTION); |
- __ jmp(&exit_label_); |
+ __ jmp(&return_eax); |
__ bind(&stack_limit_hit); |
CallCheckStackGuardState(ebx); |
__ or_(eax, eax); |
// If returned value is non-zero, we exit with the returned value as result. |
- __ j(not_zero, &exit_label_); |
+ __ j(not_zero, &return_eax); |
__ bind(&stack_ok); |
// Load start index for later use. |
@@ -807,6 +811,9 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) { |
// Initialize backtrack stack pointer. |
+ if (global()) { |
+ __ bind(&restart); |
+ } |
__ mov(backtrack_stackpointer(), Operand(ebp, kStackHighEnd)); |
// Load previous char as initial value of current-character. |
Label at_start; |
@@ -844,10 +851,38 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) { |
__ mov(Operand(ebx, i * kPointerSize), eax); |
} |
} |
- __ mov(eax, Immediate(SUCCESS)); |
+ if (global()) { |
+ // Set success flag, since we obviously have had successful captures. |
+ __ inc(Operand(ebp, kSuccessfulCaptures)); |
+ // Capture results have been stored, so the number of remaining global |
+ // output registers is reduced by the number of stored captures. |
+ __ mov(ecx, Operand(ebp, kNumOutputRegisters)); |
+ __ sub(ecx, Immediate(num_saved_registers_)); |
+ // Check whether we have enough room for another set of capture results. |
+ __ cmp(ecx, Immediate(num_saved_registers_)); |
+ __ j(less, &exit_label_); |
+ |
+ __ mov(Operand(ebp, kNumOutputRegisters), ecx); |
+ // Advance the location for output. |
+ __ mov(ebx, Operand(ebp, kRegisterOutput)); |
+ __ add(Operand(ebp, kRegisterOutput), |
+ Immediate(num_saved_registers_ * kPointerSize)); |
+ |
+ // Loop to the start. |
+ __ jmp(&restart); |
+ } else { |
+ __ mov(eax, Immediate(SUCCESS)); |
+ } |
} |
- // Exit and return eax |
+ |
__ bind(&exit_label_); |
+ if (global()) { |
+ // Return the number of successful captures. |
+ STATIC_ASSERT(FAILURE == 0 && SUCCESS == 1); |
+ __ mov(eax, Operand(ebp, kSuccessfulCaptures)); |
+ } |
+ |
+ __ bind(&return_eax); |
// Skip esp past regexp registers. |
__ lea(esp, Operand(ebp, kBackup_ebx)); |
// Restore callee-save registers. |
@@ -877,7 +912,7 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) { |
__ or_(eax, eax); |
// If returning non-zero, we should end execution with the given |
// result as return value. |
- __ j(not_zero, &exit_label_); |
+ __ j(not_zero, &return_eax); |
__ pop(edi); |
__ pop(backtrack_stackpointer()); |
@@ -924,7 +959,7 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) { |
__ bind(&exit_with_exception); |
// Exit with Result EXCEPTION(-1) to signal thrown exception. |
__ mov(eax, EXCEPTION); |
- __ jmp(&exit_label_); |
+ __ jmp(&return_eax); |
} |
CodeDesc code_desc; |