| Index: src/jsregexp.cc
|
| ===================================================================
|
| --- src/jsregexp.cc (revision 2246)
|
| +++ src/jsregexp.cc (working copy)
|
| @@ -400,7 +400,6 @@
|
| // Prepare space for the return values.
|
| int number_of_capture_registers =
|
| (IrregexpNumberOfCaptures(FixedArray::cast(jsregexp->data())) + 1) * 2;
|
| - OffsetsVector offsets(number_of_capture_registers);
|
|
|
| #ifdef DEBUG
|
| if (FLAG_trace_regexp_bytecodes) {
|
| @@ -416,17 +415,18 @@
|
|
|
| last_match_info->EnsureSize(number_of_capture_registers + kLastMatchOverhead);
|
|
|
| - int* offsets_vector = offsets.vector();
|
| bool rc;
|
| + FixedArray* array;
|
|
|
| // Dispatch to the correct RegExp implementation.
|
| -
|
| Handle<String> original_subject = subject;
|
| Handle<FixedArray> regexp(FixedArray::cast(jsregexp->data()));
|
| if (UseNativeRegexp()) {
|
| #ifdef ARM
|
| UNREACHABLE();
|
| #else
|
| + OffsetsVector captures(number_of_capture_registers);
|
| + int* captures_vector = captures.vector();
|
| RegExpMacroAssemblerIA32::Result res;
|
| do {
|
| bool is_ascii = StringShape(*subject).IsAsciiRepresentation();
|
| @@ -436,8 +436,8 @@
|
| Handle<Code> code(RegExpImpl::IrregexpNativeCode(*regexp, is_ascii));
|
| res = RegExpMacroAssemblerIA32::Match(code,
|
| subject,
|
| - offsets_vector,
|
| - offsets.length(),
|
| + captures_vector,
|
| + captures.length(),
|
| previous_index);
|
| // If result is RETRY, the string have changed representation, and we
|
| // must restart from scratch.
|
| @@ -450,39 +450,51 @@
|
| || res == RegExpMacroAssemblerIA32::FAILURE);
|
|
|
| rc = (res == RegExpMacroAssemblerIA32::SUCCESS);
|
| + if (!rc) return Factory::null_value();
|
| +
|
| + array = last_match_info->elements();
|
| + ASSERT(array->length() >= number_of_capture_registers + kLastMatchOverhead);
|
| + // The captures come in (start, end+1) pairs.
|
| + for (int i = 0; i < number_of_capture_registers; i += 2) {
|
| + SetCapture(array, i, captures_vector[i]);
|
| + SetCapture(array, i + 1, captures_vector[i + 1]);
|
| + }
|
| #endif
|
| } else {
|
| bool is_ascii = StringShape(*subject).IsAsciiRepresentation();
|
| if (!EnsureCompiledIrregexp(jsregexp, is_ascii)) {
|
| return Handle<Object>::null();
|
| }
|
| + // Now that we have done EnsureCompiledIrregexp we can get the number of
|
| + // registers.
|
| + int number_of_registers =
|
| + IrregexpNumberOfRegisters(FixedArray::cast(jsregexp->data()));
|
| + OffsetsVector registers(number_of_registers);
|
| + int* register_vector = registers.vector();
|
| for (int i = number_of_capture_registers - 1; i >= 0; i--) {
|
| - offsets_vector[i] = -1;
|
| + register_vector[i] = -1;
|
| }
|
| Handle<ByteArray> byte_codes(IrregexpByteCode(*regexp, is_ascii));
|
|
|
| rc = IrregexpInterpreter::Match(byte_codes,
|
| subject,
|
| - offsets_vector,
|
| + register_vector,
|
| previous_index);
|
| - }
|
| + if (!rc) return Factory::null_value();
|
|
|
| - // Handle results from RegExp implementation.
|
| -
|
| - if (!rc) {
|
| - return Factory::null_value();
|
| + array = last_match_info->elements();
|
| + ASSERT(array->length() >= number_of_capture_registers + kLastMatchOverhead);
|
| + // The captures come in (start, end+1) pairs.
|
| + for (int i = 0; i < number_of_capture_registers; i += 2) {
|
| + SetCapture(array, i, register_vector[i]);
|
| + SetCapture(array, i + 1, register_vector[i + 1]);
|
| + }
|
| }
|
|
|
| - FixedArray* array = last_match_info->elements();
|
| - ASSERT(array->length() >= number_of_capture_registers + kLastMatchOverhead);
|
| - // The captures come in (start, end+1) pairs.
|
| SetLastCaptureCount(array, number_of_capture_registers);
|
| SetLastSubject(array, *original_subject);
|
| SetLastInput(array, *original_subject);
|
| - for (int i = 0; i < number_of_capture_registers; i+=2) {
|
| - SetCapture(array, i, offsets_vector[i]);
|
| - SetCapture(array, i + 1, offsets_vector[i + 1]);
|
| - }
|
| +
|
| return last_match_info;
|
| }
|
|
|
| @@ -891,12 +903,13 @@
|
| // The "+1" is to avoid a push_limit of zero if stack_limit_slack() is 1.
|
| const int push_limit = (assembler->stack_limit_slack() + 1) / 2;
|
|
|
| + // Count pushes performed to force a stack limit check occasionally.
|
| + int pushes = 0;
|
| +
|
| for (int reg = 0; reg <= max_register; reg++) {
|
| if (!affected_registers.Get(reg)) {
|
| continue;
|
| }
|
| - // Count pushes performed to force a stack limit check occasionally.
|
| - int pushes = 0;
|
|
|
| // The chronologically first deferred action in the trace
|
| // is used to infer the action needed to restore a register
|
| @@ -1880,7 +1893,8 @@
|
| uint32_t differing_bits = (from ^ to);
|
| // A mask and compare is only perfect if the differing bits form a
|
| // number like 00011111 with one single block of trailing 1s.
|
| - if ((differing_bits & (differing_bits + 1)) == 0) {
|
| + if ((differing_bits & (differing_bits + 1)) == 0 &&
|
| + from + differing_bits == to) {
|
| pos->determines_perfectly = true;
|
| }
|
| uint32_t common_bits = ~SmearBitsRight(differing_bits);
|
|
|