| 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;
|
|
|