Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/regexp/jsregexp.h" | 5 #include "src/regexp/jsregexp.h" |
| 6 | 6 |
| 7 #include "src/ast/ast.h" | 7 #include "src/ast/ast.h" |
| 8 #include "src/base/platform/platform.h" | 8 #include "src/base/platform/platform.h" |
| 9 #include "src/compilation-cache.h" | 9 #include "src/compilation-cache.h" |
| 10 #include "src/compiler.h" | 10 #include "src/compiler.h" |
| 11 #include "src/execution.h" | 11 #include "src/execution.h" |
| 12 #include "src/factory.h" | 12 #include "src/factory.h" |
| 13 #include "src/isolate-inl.h" | 13 #include "src/isolate-inl.h" |
| 14 #include "src/messages.h" | 14 #include "src/messages.h" |
| 15 #include "src/ostreams.h" | 15 #include "src/ostreams.h" |
| 16 #include "src/regexp/interpreter-irregexp.h" | 16 #include "src/regexp/interpreter-irregexp.h" |
| 17 #include "src/regexp/jsregexp-inl.h" | 17 #include "src/regexp/jsregexp-inl.h" |
| 18 #include "src/regexp/regexp-macro-assembler.h" | 18 #include "src/regexp/regexp-macro-assembler.h" |
| 19 #include "src/regexp/regexp-macro-assembler-irregexp.h" | 19 #include "src/regexp/regexp-macro-assembler-irregexp.h" |
| 20 #include "src/regexp/regexp-macro-assembler-tracer.h" | 20 #include "src/regexp/regexp-macro-assembler-tracer.h" |
| 21 #include "src/regexp/regexp-parser.h" | 21 #include "src/regexp/regexp-parser.h" |
| 22 #include "src/regexp/regexp-stack.h" | 22 #include "src/regexp/regexp-stack.h" |
| 23 #include "src/runtime/runtime.h" | 23 #include "src/runtime/runtime.h" |
| 24 #include "src/splay-tree-inl.h" | 24 #include "src/splay-tree-inl.h" |
| 25 #include "src/string-search.h" | 25 #include "src/string-search.h" |
| 26 #include "src/unicode-decoder.h" | 26 #include "src/unicode-decoder.h" |
| 27 | 27 |
| 28 #ifdef V8_I18N_SUPPORT | |
| 29 #include "unicode/uset.h" | |
| 30 #include "unicode/utypes.h" | |
| 31 #endif // V8_I18N_SUPPORT | |
| 32 | |
| 28 #ifndef V8_INTERPRETED_REGEXP | 33 #ifndef V8_INTERPRETED_REGEXP |
| 29 #if V8_TARGET_ARCH_IA32 | 34 #if V8_TARGET_ARCH_IA32 |
| 30 #include "src/regexp/ia32/regexp-macro-assembler-ia32.h" | 35 #include "src/regexp/ia32/regexp-macro-assembler-ia32.h" |
| 31 #elif V8_TARGET_ARCH_X64 | 36 #elif V8_TARGET_ARCH_X64 |
| 32 #include "src/regexp/x64/regexp-macro-assembler-x64.h" | 37 #include "src/regexp/x64/regexp-macro-assembler-x64.h" |
| 33 #elif V8_TARGET_ARCH_ARM64 | 38 #elif V8_TARGET_ARCH_ARM64 |
| 34 #include "src/regexp/arm64/regexp-macro-assembler-arm64.h" | 39 #include "src/regexp/arm64/regexp-macro-assembler-arm64.h" |
| 35 #elif V8_TARGET_ARCH_ARM | 40 #elif V8_TARGET_ARCH_ARM |
| 36 #include "src/regexp/arm/regexp-macro-assembler-arm.h" | 41 #include "src/regexp/arm/regexp-macro-assembler-arm.h" |
| 37 #elif V8_TARGET_ARCH_PPC | 42 #elif V8_TARGET_ARCH_PPC |
| (...skipping 3375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3413 void TextNode::MakeCaseIndependent(Isolate* isolate, bool is_one_byte) { | 3418 void TextNode::MakeCaseIndependent(Isolate* isolate, bool is_one_byte) { |
| 3414 int element_count = elements()->length(); | 3419 int element_count = elements()->length(); |
| 3415 for (int i = 0; i < element_count; i++) { | 3420 for (int i = 0; i < element_count; i++) { |
| 3416 TextElement elm = elements()->at(i); | 3421 TextElement elm = elements()->at(i); |
| 3417 if (elm.text_type() == TextElement::CHAR_CLASS) { | 3422 if (elm.text_type() == TextElement::CHAR_CLASS) { |
| 3418 RegExpCharacterClass* cc = elm.char_class(); | 3423 RegExpCharacterClass* cc = elm.char_class(); |
| 3419 // None of the standard character classes is different in the case | 3424 // None of the standard character classes is different in the case |
| 3420 // independent case and it slows us down if we don't know that. | 3425 // independent case and it slows us down if we don't know that. |
| 3421 if (cc->is_standard(zone())) continue; | 3426 if (cc->is_standard(zone())) continue; |
| 3422 ZoneList<CharacterRange>* ranges = cc->ranges(zone()); | 3427 ZoneList<CharacterRange>* ranges = cc->ranges(zone()); |
| 3423 int range_count = ranges->length(); | 3428 CharacterRange::AddCaseEquivalents(isolate, zone(), ranges, is_one_byte); |
| 3424 for (int j = 0; j < range_count; j++) { | |
| 3425 ranges->at(j).AddCaseEquivalents(isolate, zone(), ranges, is_one_byte); | |
| 3426 } | |
| 3427 } | 3429 } |
| 3428 } | 3430 } |
| 3429 } | 3431 } |
| 3430 | 3432 |
| 3431 | 3433 |
| 3432 int TextNode::GreedyLoopTextLength() { return Length(); } | 3434 int TextNode::GreedyLoopTextLength() { return Length(); } |
| 3433 | 3435 |
| 3434 | 3436 |
| 3435 RegExpNode* TextNode::GetSuccessorOfOmnivorousTextNode( | 3437 RegExpNode* TextNode::GetSuccessorOfOmnivorousTextNode( |
| 3436 RegExpCompiler* compiler) { | 3438 RegExpCompiler* compiler) { |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3579 AlternativeGeneration* at(int i) { | 3581 AlternativeGeneration* at(int i) { |
| 3580 return alt_gens_[i]; | 3582 return alt_gens_[i]; |
| 3581 } | 3583 } |
| 3582 | 3584 |
| 3583 private: | 3585 private: |
| 3584 static const int kAFew = 10; | 3586 static const int kAFew = 10; |
| 3585 ZoneList<AlternativeGeneration*> alt_gens_; | 3587 ZoneList<AlternativeGeneration*> alt_gens_; |
| 3586 AlternativeGeneration a_few_alt_gens_[kAFew]; | 3588 AlternativeGeneration a_few_alt_gens_[kAFew]; |
| 3587 }; | 3589 }; |
| 3588 | 3590 |
| 3589 | |
| 3590 static const uc32 kLeadSurrogateStart = 0xd800; | |
| 3591 static const uc32 kLeadSurrogateEnd = 0xdbff; | |
| 3592 static const uc32 kTrailSurrogateStart = 0xdc00; | |
| 3593 static const uc32 kTrailSurrogateEnd = 0xdfff; | |
| 3594 static const uc32 kNonBmpStart = 0x10000; | |
| 3595 static const uc32 kNonBmpEnd = 0x10ffff; | |
| 3596 static const uc32 kRangeEndMarker = 0x110000; | 3591 static const uc32 kRangeEndMarker = 0x110000; |
| 3597 | 3592 |
| 3598 // The '2' variant is has inclusive from and exclusive to. | 3593 // The '2' variant is has inclusive from and exclusive to. |
| 3599 // This covers \s as defined in ECMA-262 5.1, 15.10.2.12, | 3594 // This covers \s as defined in ECMA-262 5.1, 15.10.2.12, |
| 3600 // which include WhiteSpace (7.2) or LineTerminator (7.3) values. | 3595 // which include WhiteSpace (7.2) or LineTerminator (7.3) values. |
| 3601 static const int kSpaceRanges[] = { | 3596 static const int kSpaceRanges[] = { |
| 3602 '\t', '\r' + 1, ' ', ' ' + 1, 0x00A0, 0x00A1, 0x1680, 0x1681, | 3597 '\t', '\r' + 1, ' ', ' ' + 1, 0x00A0, 0x00A1, 0x1680, 0x1681, |
| 3603 0x180E, 0x180F, 0x2000, 0x200B, 0x2028, 0x202A, 0x202F, 0x2030, | 3598 0x180E, 0x180F, 0x2000, 0x200B, 0x2028, 0x202A, 0x202F, 0x2030, |
| 3604 0x205F, 0x2060, 0x3000, 0x3001, 0xFEFF, 0xFF00, kRangeEndMarker}; | 3599 0x205F, 0x2060, 0x3000, 0x3001, 0xFEFF, 0xFF00, kRangeEndMarker}; |
| 3605 static const int kSpaceRangeCount = arraysize(kSpaceRanges); | 3600 static const int kSpaceRangeCount = arraysize(kSpaceRanges); |
| (...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4388 } | 4383 } |
| 4389 | 4384 |
| 4390 LimitResult limit_result = LimitVersions(compiler, trace); | 4385 LimitResult limit_result = LimitVersions(compiler, trace); |
| 4391 if (limit_result == DONE) return; | 4386 if (limit_result == DONE) return; |
| 4392 DCHECK(limit_result == CONTINUE); | 4387 DCHECK(limit_result == CONTINUE); |
| 4393 | 4388 |
| 4394 RecursionCheck rc(compiler); | 4389 RecursionCheck rc(compiler); |
| 4395 | 4390 |
| 4396 DCHECK_EQ(start_reg_ + 1, end_reg_); | 4391 DCHECK_EQ(start_reg_ + 1, end_reg_); |
| 4397 if (compiler->ignore_case()) { | 4392 if (compiler->ignore_case()) { |
| 4398 assembler->CheckNotBackReferenceIgnoreCase(start_reg_, read_backward(), | 4393 assembler->CheckNotBackReferenceIgnoreCase( |
| 4399 trace->backtrack()); | 4394 start_reg_, read_backward(), compiler->unicode(), trace->backtrack()); |
| 4400 } else { | 4395 } else { |
| 4401 assembler->CheckNotBackReference(start_reg_, read_backward(), | 4396 assembler->CheckNotBackReference(start_reg_, read_backward(), |
| 4402 trace->backtrack()); | 4397 trace->backtrack()); |
| 4403 } | 4398 } |
| 4404 // We are going to advance backward, so we may end up at the start. | 4399 // We are going to advance backward, so we may end up at the start. |
| 4405 if (read_backward()) trace->set_at_start(Trace::UNKNOWN); | 4400 if (read_backward()) trace->set_at_start(Trace::UNKNOWN); |
| 4406 on_success()->Emit(compiler, trace); | 4401 on_success()->Emit(compiler, trace); |
| 4407 } | 4402 } |
| 4408 | 4403 |
| 4409 | 4404 |
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4859 return true; | 4854 return true; |
| 4860 } | 4855 } |
| 4861 if (CompareInverseRanges(set_.ranges(zone), kWordRanges, kWordRangeCount)) { | 4856 if (CompareInverseRanges(set_.ranges(zone), kWordRanges, kWordRangeCount)) { |
| 4862 set_.set_standard_set_type('W'); | 4857 set_.set_standard_set_type('W'); |
| 4863 return true; | 4858 return true; |
| 4864 } | 4859 } |
| 4865 return false; | 4860 return false; |
| 4866 } | 4861 } |
| 4867 | 4862 |
| 4868 | 4863 |
| 4869 bool RegExpCharacterClass::NeedsDesugaringForUnicode(Zone* zone) { | |
| 4870 ZoneList<CharacterRange>* ranges = this->ranges(zone); | |
| 4871 CharacterRange::Canonicalize(ranges); | |
| 4872 for (int i = ranges->length() - 1; i >= 0; i--) { | |
| 4873 uc32 from = ranges->at(i).from(); | |
| 4874 uc32 to = ranges->at(i).to(); | |
| 4875 // Check for non-BMP characters. | |
| 4876 if (to >= kNonBmpStart) return true; | |
| 4877 // Check for lone surrogates. | |
| 4878 if (from <= kTrailSurrogateEnd && to >= kLeadSurrogateStart) return true; | |
| 4879 } | |
| 4880 return false; | |
| 4881 } | |
| 4882 | |
| 4883 | |
| 4884 UnicodeRangeSplitter::UnicodeRangeSplitter(Zone* zone, | 4864 UnicodeRangeSplitter::UnicodeRangeSplitter(Zone* zone, |
| 4885 ZoneList<CharacterRange>* base) | 4865 ZoneList<CharacterRange>* base) |
| 4886 : zone_(zone), | 4866 : zone_(zone), |
| 4887 table_(zone), | 4867 table_(zone), |
| 4888 bmp_(nullptr), | 4868 bmp_(nullptr), |
| 4889 lead_surrogates_(nullptr), | 4869 lead_surrogates_(nullptr), |
| 4890 trail_surrogates_(nullptr), | 4870 trail_surrogates_(nullptr), |
| 4891 non_bmp_(nullptr) { | 4871 non_bmp_(nullptr) { |
| 4892 // The unicode range splitter categorizes given character ranges into: | 4872 // The unicode range splitter categorizes given character ranges into: |
| 4893 // - Code points from the BMP representable by one code unit. | 4873 // - Code points from the BMP representable by one code unit. |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5113 optional_trail->AddAlternative( | 5093 optional_trail->AddAlternative( |
| 5114 GuardedAlternative(TextNode::CreateForCharacterRanges( | 5094 GuardedAlternative(TextNode::CreateForCharacterRanges( |
| 5115 zone, trail_surrogates, false, on_success))); | 5095 zone, trail_surrogates, false, on_success))); |
| 5116 optional_trail->AddAlternative(GuardedAlternative(on_success)); | 5096 optional_trail->AddAlternative(GuardedAlternative(on_success)); |
| 5117 RegExpNode* optional_pair = TextNode::CreateForCharacterRanges( | 5097 RegExpNode* optional_pair = TextNode::CreateForCharacterRanges( |
| 5118 zone, lead_surrogates, false, optional_trail); | 5098 zone, lead_surrogates, false, optional_trail); |
| 5119 result->AddAlternative(GuardedAlternative(optional_pair)); | 5099 result->AddAlternative(GuardedAlternative(optional_pair)); |
| 5120 } | 5100 } |
| 5121 | 5101 |
| 5122 | 5102 |
| 5103 void AddUnicodeCaseEquivalents(RegExpCompiler* compiler, | |
| 5104 ZoneList<CharacterRange>* ranges) { | |
| 5105 #ifdef V8_I18N_SUPPORT | |
| 5106 // Use ICU to compute the case fold closure over the ranges. | |
| 5107 DCHECK(compiler->unicode()); | |
| 5108 DCHECK(compiler->ignore_case()); | |
| 5109 USet* set = uset_openEmpty(); | |
| 5110 for (int i = 0; i < ranges->length(); i++) { | |
| 5111 uset_addRange(set, ranges->at(i).from(), ranges->at(i).to()); | |
| 5112 } | |
| 5113 ranges->Clear(); | |
| 5114 uset_closeOver(set, USET_CASE_INSENSITIVE); | |
| 5115 // Full case mapping map single characters to multiple characters. | |
| 5116 // Those are represented as strings in the set. Remove them so that | |
| 5117 // we end up with only simple and common case mappings. | |
| 5118 uset_removeAllStrings(set); | |
| 5119 int item_count = uset_getItemCount(set); | |
| 5120 int item_result = 0; | |
| 5121 UErrorCode ec = U_ZERO_ERROR; | |
| 5122 Zone* zone = compiler->zone(); | |
| 5123 for (int i = 0; i < item_count; i++) { | |
| 5124 uc32 start = 0; | |
| 5125 uc32 end = 0; | |
| 5126 item_result += uset_getItem(set, i, &start, &end, nullptr, 0, &ec); | |
| 5127 ranges->Add(CharacterRange::Range(start, end), zone); | |
| 5128 } | |
| 5129 // No errors and everything we collected have been ranges. | |
| 5130 DCHECK_EQ(U_ZERO_ERROR, ec); | |
| 5131 DCHECK_EQ(0, item_result); | |
| 5132 uset_close(set); | |
| 5133 #else | |
| 5134 // Fallback if ICU is not included. | |
| 5135 CharacterRange::AddCaseEquivalents(compiler->isolate(), compiler->zone(), | |
| 5136 ranges, compiler->one_byte()); | |
| 5137 #endif // V8_I18N_SUPPORT | |
| 5138 CharacterRange::Canonicalize(ranges); | |
| 5139 } | |
| 5140 | |
| 5141 | |
| 5123 RegExpNode* RegExpCharacterClass::ToNode(RegExpCompiler* compiler, | 5142 RegExpNode* RegExpCharacterClass::ToNode(RegExpCompiler* compiler, |
| 5124 RegExpNode* on_success) { | 5143 RegExpNode* on_success) { |
| 5125 set_.Canonicalize(); | 5144 set_.Canonicalize(); |
| 5126 Zone* zone = compiler->zone(); | 5145 Zone* zone = compiler->zone(); |
| 5127 ZoneList<CharacterRange>* ranges = this->ranges(zone); | 5146 ZoneList<CharacterRange>* ranges = this->ranges(zone); |
| 5147 if (compiler->unicode() && compiler->ignore_case()) { | |
| 5148 AddUnicodeCaseEquivalents(compiler, ranges); | |
| 5149 } | |
| 5128 if (compiler->unicode() && !compiler->one_byte()) { | 5150 if (compiler->unicode() && !compiler->one_byte()) { |
| 5129 if (is_negated()) { | 5151 if (is_negated()) { |
| 5130 ZoneList<CharacterRange>* negated = | 5152 ZoneList<CharacterRange>* negated = |
| 5131 new (zone) ZoneList<CharacterRange>(2, zone); | 5153 new (zone) ZoneList<CharacterRange>(2, zone); |
| 5132 CharacterRange::Negate(ranges, negated, zone); | 5154 CharacterRange::Negate(ranges, negated, zone); |
| 5133 ranges = negated; | 5155 ranges = negated; |
| 5134 } | 5156 } |
| 5135 if (ranges->length() == 0) { | 5157 if (ranges->length() == 0) { |
| 5136 // No matches possible. | 5158 // No matches possible. |
| 5137 return new (zone) EndNode(EndNode::BACKTRACK, zone); | 5159 return new (zone) EndNode(EndNode::BACKTRACK, zone); |
| (...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5846 | 5868 |
| 5847 | 5869 |
| 5848 Vector<const int> CharacterRange::GetWordBounds() { | 5870 Vector<const int> CharacterRange::GetWordBounds() { |
| 5849 return Vector<const int>(kWordRanges, kWordRangeCount - 1); | 5871 return Vector<const int>(kWordRanges, kWordRangeCount - 1); |
| 5850 } | 5872 } |
| 5851 | 5873 |
| 5852 | 5874 |
| 5853 void CharacterRange::AddCaseEquivalents(Isolate* isolate, Zone* zone, | 5875 void CharacterRange::AddCaseEquivalents(Isolate* isolate, Zone* zone, |
| 5854 ZoneList<CharacterRange>* ranges, | 5876 ZoneList<CharacterRange>* ranges, |
| 5855 bool is_one_byte) { | 5877 bool is_one_byte) { |
| 5856 uc32 bottom = from(); | 5878 int range_count = ranges->length(); |
| 5857 uc32 top = to(); | 5879 for (int i = 0; i < range_count; i++) { |
| 5858 // Nothing to be done for surrogates. | 5880 CharacterRange range = ranges->at(i); |
| 5859 if (bottom >= kLeadSurrogateStart && top <= kTrailSurrogateEnd) return; | 5881 uc32 bottom = range.from(); |
| 5860 if (is_one_byte && !RangeContainsLatin1Equivalents(*this)) { | 5882 uc32 top = range.to(); |
| 5861 if (bottom > String::kMaxOneByteCharCode) return; | 5883 // Nothing to be done for surrogates. |
| 5862 if (top > String::kMaxOneByteCharCode) top = String::kMaxOneByteCharCode; | 5884 if (bottom >= kLeadSurrogateStart && top <= kTrailSurrogateEnd) return; |
| 5863 } | 5885 if (is_one_byte && !RangeContainsLatin1Equivalents(range)) { |
| 5864 unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth]; | 5886 if (bottom > String::kMaxOneByteCharCode) return; |
| 5865 if (top == bottom) { | 5887 if (top > String::kMaxOneByteCharCode) top = String::kMaxOneByteCharCode; |
| 5888 } | |
| 5889 unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth]; | |
| 5890 if (top == bottom) { | |
| 5866 // If this is a singleton we just expand the one character. | 5891 // If this is a singleton we just expand the one character. |
|
brucedawson
2016/01/29 18:49:15
The indenting of this line - and the rest of the f
| |
| 5867 int length = isolate->jsregexp_uncanonicalize()->get(bottom, '\0', chars); | 5892 int length = isolate->jsregexp_uncanonicalize()->get(bottom, '\0', chars); |
| 5868 for (int i = 0; i < length; i++) { | 5893 for (int i = 0; i < length; i++) { |
| 5869 uc32 chr = chars[i]; | 5894 uc32 chr = chars[i]; |
| 5870 if (chr != bottom) { | 5895 if (chr != bottom) { |
| 5871 ranges->Add(CharacterRange::Singleton(chars[i]), zone); | 5896 ranges->Add(CharacterRange::Singleton(chars[i]), zone); |
| 5872 } | 5897 } |
| 5873 } | 5898 } |
| 5874 } else { | 5899 } else { |
| 5875 // If this is a range we expand the characters block by block, | 5900 // If this is a range we expand the characters block by block, |
| 5876 // expanding contiguous subranges (blocks) one at a time. | 5901 // expanding contiguous subranges (blocks) one at a time. |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 5907 uc32 c = range[i]; | 5932 uc32 c = range[i]; |
| 5908 uc32 range_from = c - (block_end - pos); | 5933 uc32 range_from = c - (block_end - pos); |
| 5909 uc32 range_to = c - (block_end - end); | 5934 uc32 range_to = c - (block_end - end); |
| 5910 if (!(bottom <= range_from && range_to <= top)) { | 5935 if (!(bottom <= range_from && range_to <= top)) { |
| 5911 ranges->Add(CharacterRange(range_from, range_to), zone); | 5936 ranges->Add(CharacterRange(range_from, range_to), zone); |
| 5912 } | 5937 } |
| 5913 } | 5938 } |
| 5914 pos = end + 1; | 5939 pos = end + 1; |
| 5915 } | 5940 } |
| 5916 } | 5941 } |
| 5942 } | |
| 5917 } | 5943 } |
| 5918 | 5944 |
| 5919 | 5945 |
| 5920 bool CharacterRange::IsCanonical(ZoneList<CharacterRange>* ranges) { | 5946 bool CharacterRange::IsCanonical(ZoneList<CharacterRange>* ranges) { |
| 5921 DCHECK_NOT_NULL(ranges); | 5947 DCHECK_NOT_NULL(ranges); |
| 5922 int n = ranges->length(); | 5948 int n = ranges->length(); |
| 5923 if (n <= 1) return true; | 5949 if (n <= 1) return true; |
| 5924 int max = ranges->at(0).to(); | 5950 int max = ranges->at(0).to(); |
| 5925 for (int i = 1; i < n; i++) { | 5951 for (int i = 1; i < n; i++) { |
| 5926 CharacterRange next_range = ranges->at(i); | 5952 CharacterRange next_range = ranges->at(i); |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6277 int cp_offset = 0; | 6303 int cp_offset = 0; |
| 6278 for (int i = 0; i < element_count; i++) { | 6304 for (int i = 0; i < element_count; i++) { |
| 6279 TextElement& elm = elements()->at(i); | 6305 TextElement& elm = elements()->at(i); |
| 6280 elm.set_cp_offset(cp_offset); | 6306 elm.set_cp_offset(cp_offset); |
| 6281 cp_offset += elm.length(); | 6307 cp_offset += elm.length(); |
| 6282 } | 6308 } |
| 6283 } | 6309 } |
| 6284 | 6310 |
| 6285 | 6311 |
| 6286 void Analysis::VisitText(TextNode* that) { | 6312 void Analysis::VisitText(TextNode* that) { |
| 6287 if (ignore_case_) { | 6313 if (ignore_case()) { |
| 6288 that->MakeCaseIndependent(isolate(), is_one_byte_); | 6314 that->MakeCaseIndependent(isolate(), is_one_byte_); |
| 6289 } | 6315 } |
| 6290 EnsureAnalyzed(that->on_success()); | 6316 EnsureAnalyzed(that->on_success()); |
| 6291 if (!has_failed()) { | 6317 if (!has_failed()) { |
| 6292 that->CalculateOffsets(); | 6318 that->CalculateOffsets(); |
| 6293 } | 6319 } |
| 6294 } | 6320 } |
| 6295 | 6321 |
| 6296 | 6322 |
| 6297 void Analysis::VisitAction(ActionNode* that) { | 6323 void Analysis::VisitAction(ActionNode* that) { |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6642 // put because they had not been calculated yet. | 6668 // put because they had not been calculated yet. |
| 6643 if (node != NULL) { | 6669 if (node != NULL) { |
| 6644 node = node->FilterOneByte(RegExpCompiler::kMaxRecursion, ignore_case); | 6670 node = node->FilterOneByte(RegExpCompiler::kMaxRecursion, ignore_case); |
| 6645 } | 6671 } |
| 6646 } else if (compiler.unicode() && (is_global || is_sticky)) { | 6672 } else if (compiler.unicode() && (is_global || is_sticky)) { |
| 6647 node = OptionallyStepBackToLeadSurrogate(&compiler, node); | 6673 node = OptionallyStepBackToLeadSurrogate(&compiler, node); |
| 6648 } | 6674 } |
| 6649 | 6675 |
| 6650 if (node == NULL) node = new(zone) EndNode(EndNode::BACKTRACK, zone); | 6676 if (node == NULL) node = new(zone) EndNode(EndNode::BACKTRACK, zone); |
| 6651 data->node = node; | 6677 data->node = node; |
| 6652 Analysis analysis(isolate, ignore_case, is_one_byte); | 6678 Analysis analysis(isolate, flags, is_one_byte); |
| 6653 analysis.EnsureAnalyzed(node); | 6679 analysis.EnsureAnalyzed(node); |
| 6654 if (analysis.has_failed()) { | 6680 if (analysis.has_failed()) { |
| 6655 const char* error_message = analysis.error_message(); | 6681 const char* error_message = analysis.error_message(); |
| 6656 return CompilationResult(isolate, error_message); | 6682 return CompilationResult(isolate, error_message); |
| 6657 } | 6683 } |
| 6658 | 6684 |
| 6659 // Create the correct assembler for the architecture. | 6685 // Create the correct assembler for the architecture. |
| 6660 #ifndef V8_INTERPRETED_REGEXP | 6686 #ifndef V8_INTERPRETED_REGEXP |
| 6661 // Native regexp implementation. | 6687 // Native regexp implementation. |
| 6662 | 6688 |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6829 | 6855 |
| 6830 | 6856 |
| 6831 void RegExpResultsCache::Clear(FixedArray* cache) { | 6857 void RegExpResultsCache::Clear(FixedArray* cache) { |
| 6832 for (int i = 0; i < kRegExpResultsCacheSize; i++) { | 6858 for (int i = 0; i < kRegExpResultsCacheSize; i++) { |
| 6833 cache->set(i, Smi::FromInt(0)); | 6859 cache->set(i, Smi::FromInt(0)); |
| 6834 } | 6860 } |
| 6835 } | 6861 } |
| 6836 | 6862 |
| 6837 } // namespace internal | 6863 } // namespace internal |
| 6838 } // namespace v8 | 6864 } // namespace v8 |
| OLD | NEW |