OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
11 // with the distribution. | 11 // with the distribution. |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
422 // THIS SHOULD NOT HAPPEN. We already pre-parsed it successfully once. | 422 // THIS SHOULD NOT HAPPEN. We already pre-parsed it successfully once. |
423 ThrowRegExpException(re, | 423 ThrowRegExpException(re, |
424 pattern, | 424 pattern, |
425 compile_data.error, | 425 compile_data.error, |
426 "malformed_regexp"); | 426 "malformed_regexp"); |
427 return false; | 427 return false; |
428 } | 428 } |
429 RegExpEngine::CompilationResult result = | 429 RegExpEngine::CompilationResult result = |
430 RegExpEngine::Compile(&compile_data, | 430 RegExpEngine::Compile(&compile_data, |
431 flags.is_ignore_case(), | 431 flags.is_ignore_case(), |
432 flags.is_global(), | |
432 flags.is_multiline(), | 433 flags.is_multiline(), |
433 pattern, | 434 pattern, |
434 sample_subject, | 435 sample_subject, |
435 is_ascii); | 436 is_ascii); |
436 if (result.error_message != NULL) { | 437 if (result.error_message != NULL) { |
437 // Unable to compile regexp. | 438 // Unable to compile regexp. |
438 Handle<String> error_message = | 439 Handle<String> error_message = |
439 isolate->factory()->NewStringFromUtf8(CStrVector(result.error_message)); | 440 isolate->factory()->NewStringFromUtf8(CStrVector(result.error_message)); |
440 CreateRegExpErrorObjectAndThrow(re, is_ascii, error_message, isolate); | 441 CreateRegExpErrorObjectAndThrow(re, is_ascii, error_message, isolate); |
441 return false; | 442 return false; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
508 // Byte-code regexp needs space allocated for all its registers. | 509 // Byte-code regexp needs space allocated for all its registers. |
509 return IrregexpNumberOfRegisters(FixedArray::cast(regexp->data())); | 510 return IrregexpNumberOfRegisters(FixedArray::cast(regexp->data())); |
510 #else // V8_INTERPRETED_REGEXP | 511 #else // V8_INTERPRETED_REGEXP |
511 // Native regexp only needs room to output captures. Registers are handled | 512 // Native regexp only needs room to output captures. Registers are handled |
512 // internally. | 513 // internally. |
513 return (IrregexpNumberOfCaptures(FixedArray::cast(regexp->data())) + 1) * 2; | 514 return (IrregexpNumberOfCaptures(FixedArray::cast(regexp->data())) + 1) * 2; |
514 #endif // V8_INTERPRETED_REGEXP | 515 #endif // V8_INTERPRETED_REGEXP |
515 } | 516 } |
516 | 517 |
517 | 518 |
518 RegExpImpl::IrregexpResult RegExpImpl::IrregexpExecOnce( | 519 int RegExpImpl::GlobalOffsetsVectorSize(Handle<JSRegExp> regexp, |
520 int registers_per_match, | |
521 int* max_matches) { | |
522 #ifdef V8_INTERPRETED_REGEXP | |
523 // Global loop in interpreted regexp is not implemented. Therefore we choose | |
524 // the size of the offsets vector so that it can only store one match. | |
525 *max_matches = 1; | |
526 return registers_per_match; | |
527 #else // V8_INTERPRETED_REGEXP | |
528 int size = Max(registers_per_match, OffsetsVector::kStaticOffsetsVectorSize); | |
529 *max_matches = size / registers_per_match; | |
530 return size; | |
531 #endif // V8_INTERPRETED_REGEXP | |
532 } | |
533 | |
534 | |
535 int RegExpImpl::IrregexpExecRaw( | |
519 Handle<JSRegExp> regexp, | 536 Handle<JSRegExp> regexp, |
520 Handle<String> subject, | 537 Handle<String> subject, |
521 int index, | 538 int index, |
522 Vector<int> output) { | 539 Vector<int> output) { |
523 Isolate* isolate = regexp->GetIsolate(); | 540 Isolate* isolate = regexp->GetIsolate(); |
524 | 541 |
525 Handle<FixedArray> irregexp(FixedArray::cast(regexp->data()), isolate); | 542 Handle<FixedArray> irregexp(FixedArray::cast(regexp->data()), isolate); |
526 | 543 |
527 ASSERT(index >= 0); | 544 ASSERT(index >= 0); |
528 ASSERT(index <= subject->length()); | 545 ASSERT(index <= subject->length()); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
610 #endif | 627 #endif |
611 int required_registers = RegExpImpl::IrregexpPrepare(jsregexp, subject); | 628 int required_registers = RegExpImpl::IrregexpPrepare(jsregexp, subject); |
612 if (required_registers < 0) { | 629 if (required_registers < 0) { |
613 // Compiling failed with an exception. | 630 // Compiling failed with an exception. |
614 ASSERT(isolate->has_pending_exception()); | 631 ASSERT(isolate->has_pending_exception()); |
615 return Handle<Object>::null(); | 632 return Handle<Object>::null(); |
616 } | 633 } |
617 | 634 |
618 OffsetsVector registers(required_registers, isolate); | 635 OffsetsVector registers(required_registers, isolate); |
619 | 636 |
620 IrregexpResult res = RegExpImpl::IrregexpExecOnce( | 637 int res = RegExpImpl::IrregexpExecRaw( |
621 jsregexp, subject, previous_index, Vector<int>(registers.vector(), | 638 jsregexp, subject, previous_index, Vector<int>(registers.vector(), |
622 registers.length())); | 639 registers.length())); |
623 if (res == RE_SUCCESS) { | 640 if (res == RE_SUCCESS) { |
624 int capture_register_count = | 641 int capture_register_count = |
625 (IrregexpNumberOfCaptures(FixedArray::cast(jsregexp->data())) + 1) * 2; | 642 (IrregexpNumberOfCaptures(FixedArray::cast(jsregexp->data())) + 1) * 2; |
626 last_match_info->EnsureSize(capture_register_count + kLastMatchOverhead); | 643 last_match_info->EnsureSize(capture_register_count + kLastMatchOverhead); |
627 AssertNoAllocation no_gc; | 644 AssertNoAllocation no_gc; |
628 int* register_vector = registers.vector(); | 645 int* register_vector = registers.vector(); |
629 FixedArray* array = FixedArray::cast(last_match_info->elements()); | 646 FixedArray* array = FixedArray::cast(last_match_info->elements()); |
630 for (int i = 0; i < capture_register_count; i += 2) { | 647 for (int i = 0; i < capture_register_count; i += 2) { |
(...skipping 5142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5773 | 5790 |
5774 void DispatchTableConstructor::VisitAction(ActionNode* that) { | 5791 void DispatchTableConstructor::VisitAction(ActionNode* that) { |
5775 RegExpNode* target = that->on_success(); | 5792 RegExpNode* target = that->on_success(); |
5776 target->Accept(this); | 5793 target->Accept(this); |
5777 } | 5794 } |
5778 | 5795 |
5779 | 5796 |
5780 RegExpEngine::CompilationResult RegExpEngine::Compile( | 5797 RegExpEngine::CompilationResult RegExpEngine::Compile( |
5781 RegExpCompileData* data, | 5798 RegExpCompileData* data, |
5782 bool ignore_case, | 5799 bool ignore_case, |
5800 bool is_global, | |
5783 bool is_multiline, | 5801 bool is_multiline, |
5784 Handle<String> pattern, | 5802 Handle<String> pattern, |
5785 Handle<String> sample_subject, | 5803 Handle<String> sample_subject, |
5786 bool is_ascii) { | 5804 bool is_ascii) { |
5787 if ((data->capture_count + 1) * 2 - 1 > RegExpMacroAssembler::kMaxRegister) { | 5805 if ((data->capture_count + 1) * 2 - 1 > RegExpMacroAssembler::kMaxRegister) { |
5788 return IrregexpRegExpTooBig(); | 5806 return IrregexpRegExpTooBig(); |
5789 } | 5807 } |
5790 RegExpCompiler compiler(data->capture_count, ignore_case, is_ascii); | 5808 RegExpCompiler compiler(data->capture_count, ignore_case, is_ascii); |
Erik Corry
2012/05/22 08:32:46
Optimization idea (probably for the next patch): A
Yang
2012/05/22 14:48:03
This is exactly what I've been looking for! I trie
| |
5791 | 5809 |
5792 // Sample some characters from the middle of the string. | 5810 // Sample some characters from the middle of the string. |
5793 static const int kSampleSize = 128; | 5811 static const int kSampleSize = 128; |
5794 | 5812 |
5795 FlattenString(sample_subject); | 5813 FlattenString(sample_subject); |
5796 int chars_sampled = 0; | 5814 int chars_sampled = 0; |
5797 int half_way = (sample_subject->length() - kSampleSize) / 2; | 5815 int half_way = (sample_subject->length() - kSampleSize) / 2; |
5798 for (int i = Max(0, half_way); | 5816 for (int i = Max(0, half_way); |
5799 i < sample_subject->length() && chars_sampled < kSampleSize; | 5817 i < sample_subject->length() && chars_sampled < kSampleSize; |
5800 i++, chars_sampled++) { | 5818 i++, chars_sampled++) { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5876 | 5894 |
5877 // Inserted here, instead of in Assembler, because it depends on information | 5895 // Inserted here, instead of in Assembler, because it depends on information |
5878 // in the AST that isn't replicated in the Node structure. | 5896 // in the AST that isn't replicated in the Node structure. |
5879 static const int kMaxBacksearchLimit = 1024; | 5897 static const int kMaxBacksearchLimit = 1024; |
5880 if (is_end_anchored && | 5898 if (is_end_anchored && |
5881 !is_start_anchored && | 5899 !is_start_anchored && |
5882 max_length < kMaxBacksearchLimit) { | 5900 max_length < kMaxBacksearchLimit) { |
5883 macro_assembler.SetCurrentPositionFromEnd(max_length); | 5901 macro_assembler.SetCurrentPositionFromEnd(max_length); |
5884 } | 5902 } |
5885 | 5903 |
5904 macro_assembler.set_global(is_global); | |
5905 | |
5886 return compiler.Assemble(¯o_assembler, | 5906 return compiler.Assemble(¯o_assembler, |
5887 node, | 5907 node, |
5888 data->capture_count, | 5908 data->capture_count, |
5889 pattern); | 5909 pattern); |
5890 } | 5910 } |
5891 | 5911 |
5892 | 5912 |
5893 }} // namespace v8::internal | 5913 }} // namespace v8::internal |
OLD | NEW |