Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Side by Side Diff: src/runtime.cc

Issue 11896060: Correctly reset lastIndex in an RegExp object. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: . Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 1776 matching lines...) Expand 10 before | Expand all | Expand 10 after
1787 // If we still have the original map, set in-object properties directly. 1787 // If we still have the original map, set in-object properties directly.
1788 regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, source); 1788 regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, source);
1789 // Both true and false are immovable immortal objects so no need for write 1789 // Both true and false are immovable immortal objects so no need for write
1790 // barrier. 1790 // barrier.
1791 regexp->InObjectPropertyAtPut( 1791 regexp->InObjectPropertyAtPut(
1792 JSRegExp::kGlobalFieldIndex, global, SKIP_WRITE_BARRIER); 1792 JSRegExp::kGlobalFieldIndex, global, SKIP_WRITE_BARRIER);
1793 regexp->InObjectPropertyAtPut( 1793 regexp->InObjectPropertyAtPut(
1794 JSRegExp::kIgnoreCaseFieldIndex, ignoreCase, SKIP_WRITE_BARRIER); 1794 JSRegExp::kIgnoreCaseFieldIndex, ignoreCase, SKIP_WRITE_BARRIER);
1795 regexp->InObjectPropertyAtPut( 1795 regexp->InObjectPropertyAtPut(
1796 JSRegExp::kMultilineFieldIndex, multiline, SKIP_WRITE_BARRIER); 1796 JSRegExp::kMultilineFieldIndex, multiline, SKIP_WRITE_BARRIER);
1797 regexp->ResetLastIndex(); 1797 regexp->InObjectPropertyAtPut(
1798 JSRegExp::kLastIndexFieldIndex, Smi::FromInt(0), SKIP_WRITE_BARRIER);
1798 return regexp; 1799 return regexp;
1799 } 1800 }
1800 1801
1801 // Map has changed, so use generic, but slower, method. 1802 // Map has changed, so use generic, but slower, method.
1802 PropertyAttributes final = 1803 PropertyAttributes final =
1803 static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE); 1804 static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE);
1804 PropertyAttributes writable = 1805 PropertyAttributes writable =
1805 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); 1806 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
1806 Heap* heap = isolate->heap(); 1807 Heap* heap = isolate->heap();
1807 MaybeObject* result; 1808 MaybeObject* result;
(...skipping 1096 matching lines...) Expand 10 before | Expand all | Expand 10 after
2904 String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex)); 2905 String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex));
2905 int subject_len = subject->length(); 2906 int subject_len = subject->length();
2906 int pattern_len = pattern->length(); 2907 int pattern_len = pattern->length();
2907 int replacement_len = replacement->length(); 2908 int replacement_len = replacement->length();
2908 2909
2909 FindStringIndicesDispatch( 2910 FindStringIndicesDispatch(
2910 isolate, *subject, pattern, &indices, 0xffffffff, zone); 2911 isolate, *subject, pattern, &indices, 0xffffffff, zone);
2911 2912
2912 int matches = indices.length(); 2913 int matches = indices.length();
2913 if (matches == 0) { 2914 if (matches == 0) {
2914 pattern_regexp->ResetLastIndex(); 2915 JSRegExp::ResetLastIndex(isolate, pattern_regexp);
2915 return *subject; 2916 return *subject;
2916 } 2917 }
2917 2918
2918 // Detect integer overflow. 2919 // Detect integer overflow.
2919 int64_t result_len_64 = 2920 int64_t result_len_64 =
2920 (static_cast<int64_t>(replacement_len) - 2921 (static_cast<int64_t>(replacement_len) -
2921 static_cast<int64_t>(pattern_len)) * 2922 static_cast<int64_t>(pattern_len)) *
2922 static_cast<int64_t>(matches) + 2923 static_cast<int64_t>(matches) +
2923 static_cast<int64_t>(subject_len); 2924 static_cast<int64_t>(subject_len);
2924 if (result_len_64 > INT_MAX) return Failure::OutOfMemoryException(0x11); 2925 if (result_len_64 > INT_MAX) return Failure::OutOfMemoryException(0x11);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
3007 isolate, subject, regexp, replacement, last_match_info); 3008 isolate, subject, regexp, replacement, last_match_info);
3008 } 3009 }
3009 } 3010 }
3010 3011
3011 RegExpImpl::GlobalCache global_cache(regexp, subject, is_global, isolate); 3012 RegExpImpl::GlobalCache global_cache(regexp, subject, is_global, isolate);
3012 if (global_cache.HasException()) return Failure::Exception(); 3013 if (global_cache.HasException()) return Failure::Exception();
3013 3014
3014 int32_t* current_match = global_cache.FetchNext(); 3015 int32_t* current_match = global_cache.FetchNext();
3015 if (current_match == NULL) { 3016 if (current_match == NULL) {
3016 if (global_cache.HasException()) return Failure::Exception(); 3017 if (global_cache.HasException()) return Failure::Exception();
3017 regexp->ResetLastIndex(); 3018 JSRegExp::ResetLastIndex(isolate, regexp);
3018 return *subject; 3019 return *subject;
3019 } 3020 }
3020 3021
3021 // Guessing the number of parts that the final result string is built 3022 // Guessing the number of parts that the final result string is built
3022 // from. Global regexps can match any number of times, so we guess 3023 // from. Global regexps can match any number of times, so we guess
3023 // conservatively. 3024 // conservatively.
3024 int expected_parts = 3025 int expected_parts =
3025 (compiled_replacement.parts() + 1) * (is_global ? 4 : 1) + 1; 3026 (compiled_replacement.parts() + 1) * (is_global ? 4 : 1) + 1;
3026 ReplacementStringBuilder builder(isolate->heap(), 3027 ReplacementStringBuilder builder(isolate->heap(),
3027 subject, 3028 subject,
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
3106 last_match_info); 3107 last_match_info);
3107 } 3108 }
3108 } 3109 }
3109 3110
3110 RegExpImpl::GlobalCache global_cache(regexp, subject, is_global, isolate); 3111 RegExpImpl::GlobalCache global_cache(regexp, subject, is_global, isolate);
3111 if (global_cache.HasException()) return Failure::Exception(); 3112 if (global_cache.HasException()) return Failure::Exception();
3112 3113
3113 int32_t* current_match = global_cache.FetchNext(); 3114 int32_t* current_match = global_cache.FetchNext();
3114 if (current_match == NULL) { 3115 if (current_match == NULL) {
3115 if (global_cache.HasException()) return Failure::Exception(); 3116 if (global_cache.HasException()) return Failure::Exception();
3116 regexp->ResetLastIndex(); 3117 JSRegExp::ResetLastIndex(isolate, regexp);
3117 return *subject; 3118 return *subject;
3118 } 3119 }
3119 3120
3120 int start = current_match[0]; 3121 int start = current_match[0];
3121 int end = current_match[1]; 3122 int end = current_match[1];
3122 int capture_count = regexp->CaptureCount(); 3123 int capture_count = regexp->CaptureCount();
3123 int subject_length = subject->length(); 3124 int subject_length = subject->length();
3124 3125
3125 int new_length = subject_length - (end - start); 3126 int new_length = subject_length - (end - start);
3126 if (new_length == 0) return isolate->heap()->empty_string(); 3127 if (new_length == 0) return isolate->heap()->empty_string();
(...skipping 10392 matching lines...) Expand 10 before | Expand all | Expand 10 after
13519 // Handle last resort GC and make sure to allow future allocations 13520 // Handle last resort GC and make sure to allow future allocations
13520 // to grow the heap without causing GCs (if possible). 13521 // to grow the heap without causing GCs (if possible).
13521 isolate->counters()->gc_last_resort_from_js()->Increment(); 13522 isolate->counters()->gc_last_resort_from_js()->Increment();
13522 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 13523 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
13523 "Runtime::PerformGC"); 13524 "Runtime::PerformGC");
13524 } 13525 }
13525 } 13526 }
13526 13527
13527 13528
13528 } } // namespace v8::internal 13529 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698