OLD | NEW |
1 // Copyright 2012 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 |
(...skipping 1772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1783 // If we still have the original map, set in-object properties directly. | 1783 // If we still have the original map, set in-object properties directly. |
1784 regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, source); | 1784 regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, source); |
1785 // Both true and false are immovable immortal objects so no need for write | 1785 // Both true and false are immovable immortal objects so no need for write |
1786 // barrier. | 1786 // barrier. |
1787 regexp->InObjectPropertyAtPut( | 1787 regexp->InObjectPropertyAtPut( |
1788 JSRegExp::kGlobalFieldIndex, global, SKIP_WRITE_BARRIER); | 1788 JSRegExp::kGlobalFieldIndex, global, SKIP_WRITE_BARRIER); |
1789 regexp->InObjectPropertyAtPut( | 1789 regexp->InObjectPropertyAtPut( |
1790 JSRegExp::kIgnoreCaseFieldIndex, ignoreCase, SKIP_WRITE_BARRIER); | 1790 JSRegExp::kIgnoreCaseFieldIndex, ignoreCase, SKIP_WRITE_BARRIER); |
1791 regexp->InObjectPropertyAtPut( | 1791 regexp->InObjectPropertyAtPut( |
1792 JSRegExp::kMultilineFieldIndex, multiline, SKIP_WRITE_BARRIER); | 1792 JSRegExp::kMultilineFieldIndex, multiline, SKIP_WRITE_BARRIER); |
1793 regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex, | 1793 regexp->ResetLastIndex(); |
1794 Smi::FromInt(0), | |
1795 SKIP_WRITE_BARRIER); // It's a Smi. | |
1796 return regexp; | 1794 return regexp; |
1797 } | 1795 } |
1798 | 1796 |
1799 // Map has changed, so use generic, but slower, method. | 1797 // Map has changed, so use generic, but slower, method. |
1800 PropertyAttributes final = | 1798 PropertyAttributes final = |
1801 static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE); | 1799 static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE); |
1802 PropertyAttributes writable = | 1800 PropertyAttributes writable = |
1803 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); | 1801 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); |
1804 Heap* heap = isolate->heap(); | 1802 Heap* heap = isolate->heap(); |
1805 MaybeObject* result; | 1803 MaybeObject* result; |
(...skipping 1091 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2897 String* pattern = | 2895 String* pattern = |
2898 String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex)); | 2896 String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex)); |
2899 int subject_len = subject->length(); | 2897 int subject_len = subject->length(); |
2900 int pattern_len = pattern->length(); | 2898 int pattern_len = pattern->length(); |
2901 int replacement_len = replacement->length(); | 2899 int replacement_len = replacement->length(); |
2902 | 2900 |
2903 FindStringIndicesDispatch( | 2901 FindStringIndicesDispatch( |
2904 isolate, *subject, pattern, &indices, 0xffffffff, zone); | 2902 isolate, *subject, pattern, &indices, 0xffffffff, zone); |
2905 | 2903 |
2906 int matches = indices.length(); | 2904 int matches = indices.length(); |
2907 if (matches == 0) return *subject; | 2905 if (matches == 0) { |
| 2906 pattern_regexp->ResetLastIndex(); |
| 2907 return *subject; |
| 2908 } |
2908 | 2909 |
2909 // Detect integer overflow. | 2910 // Detect integer overflow. |
2910 int64_t result_len_64 = | 2911 int64_t result_len_64 = |
2911 (static_cast<int64_t>(replacement_len) - | 2912 (static_cast<int64_t>(replacement_len) - |
2912 static_cast<int64_t>(pattern_len)) * | 2913 static_cast<int64_t>(pattern_len)) * |
2913 static_cast<int64_t>(matches) + | 2914 static_cast<int64_t>(matches) + |
2914 static_cast<int64_t>(subject_len); | 2915 static_cast<int64_t>(subject_len); |
2915 if (result_len_64 > INT_MAX) return Failure::OutOfMemoryException(); | 2916 if (result_len_64 > INT_MAX) return Failure::OutOfMemoryException(); |
2916 int result_len = static_cast<int>(result_len_64); | 2917 int result_len = static_cast<int>(result_len_64); |
2917 | 2918 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2997 isolate, subject, regexp, replacement, last_match_info); | 2998 isolate, subject, regexp, replacement, last_match_info); |
2998 } | 2999 } |
2999 } | 3000 } |
3000 | 3001 |
3001 RegExpImpl::GlobalCache global_cache(regexp, subject, is_global, isolate); | 3002 RegExpImpl::GlobalCache global_cache(regexp, subject, is_global, isolate); |
3002 if (global_cache.HasException()) return Failure::Exception(); | 3003 if (global_cache.HasException()) return Failure::Exception(); |
3003 | 3004 |
3004 int32_t* current_match = global_cache.FetchNext(); | 3005 int32_t* current_match = global_cache.FetchNext(); |
3005 if (current_match == NULL) { | 3006 if (current_match == NULL) { |
3006 if (global_cache.HasException()) return Failure::Exception(); | 3007 if (global_cache.HasException()) return Failure::Exception(); |
| 3008 regexp->ResetLastIndex(); |
3007 return *subject; | 3009 return *subject; |
3008 } | 3010 } |
3009 | 3011 |
3010 // Guessing the number of parts that the final result string is built | 3012 // Guessing the number of parts that the final result string is built |
3011 // from. Global regexps can match any number of times, so we guess | 3013 // from. Global regexps can match any number of times, so we guess |
3012 // conservatively. | 3014 // conservatively. |
3013 int expected_parts = | 3015 int expected_parts = |
3014 (compiled_replacement.parts() + 1) * (is_global ? 4 : 1) + 1; | 3016 (compiled_replacement.parts() + 1) * (is_global ? 4 : 1) + 1; |
3015 ReplacementStringBuilder builder(isolate->heap(), | 3017 ReplacementStringBuilder builder(isolate->heap(), |
3016 subject, | 3018 subject, |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3095 last_match_info); | 3097 last_match_info); |
3096 } | 3098 } |
3097 } | 3099 } |
3098 | 3100 |
3099 RegExpImpl::GlobalCache global_cache(regexp, subject, is_global, isolate); | 3101 RegExpImpl::GlobalCache global_cache(regexp, subject, is_global, isolate); |
3100 if (global_cache.HasException()) return Failure::Exception(); | 3102 if (global_cache.HasException()) return Failure::Exception(); |
3101 | 3103 |
3102 int32_t* current_match = global_cache.FetchNext(); | 3104 int32_t* current_match = global_cache.FetchNext(); |
3103 if (current_match == NULL) { | 3105 if (current_match == NULL) { |
3104 if (global_cache.HasException()) return Failure::Exception(); | 3106 if (global_cache.HasException()) return Failure::Exception(); |
| 3107 regexp->ResetLastIndex(); |
3105 return *subject; | 3108 return *subject; |
3106 } | 3109 } |
3107 | 3110 |
3108 int start = current_match[0]; | 3111 int start = current_match[0]; |
3109 int end = current_match[1]; | 3112 int end = current_match[1]; |
3110 int capture_count = regexp->CaptureCount(); | 3113 int capture_count = regexp->CaptureCount(); |
3111 int subject_length = subject->length(); | 3114 int subject_length = subject->length(); |
3112 | 3115 |
3113 int new_length = subject_length - (end - start); | 3116 int new_length = subject_length - (end - start); |
3114 if (new_length == 0) return isolate->heap()->empty_string(); | 3117 if (new_length == 0) return isolate->heap()->empty_string(); |
(...skipping 10434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13549 // Handle last resort GC and make sure to allow future allocations | 13552 // Handle last resort GC and make sure to allow future allocations |
13550 // to grow the heap without causing GCs (if possible). | 13553 // to grow the heap without causing GCs (if possible). |
13551 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13554 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13552 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13555 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13553 "Runtime::PerformGC"); | 13556 "Runtime::PerformGC"); |
13554 } | 13557 } |
13555 } | 13558 } |
13556 | 13559 |
13557 | 13560 |
13558 } } // namespace v8::internal | 13561 } } // namespace v8::internal |
OLD | NEW |