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

Side by Side Diff: src/runtime.cc

Issue 10535164: Unbreak interpreted regexp. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 6 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
« no previous file with comments | « src/regexp-macro-assembler-irregexp.cc ('k') | test/cctest/test-regexp.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1730 matching lines...) Expand 10 before | Expand all | Expand 10 after
1741 // length of a string, i.e. it is always a Smi. We check anyway for security. 1741 // length of a string, i.e. it is always a Smi. We check anyway for security.
1742 CONVERT_SMI_ARG_CHECKED(index, 2); 1742 CONVERT_SMI_ARG_CHECKED(index, 2);
1743 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3); 1743 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
1744 RUNTIME_ASSERT(last_match_info->HasFastObjectElements()); 1744 RUNTIME_ASSERT(last_match_info->HasFastObjectElements());
1745 RUNTIME_ASSERT(index >= 0); 1745 RUNTIME_ASSERT(index >= 0);
1746 RUNTIME_ASSERT(index <= subject->length()); 1746 RUNTIME_ASSERT(index <= subject->length());
1747 isolate->counters()->regexp_entry_runtime()->Increment(); 1747 isolate->counters()->regexp_entry_runtime()->Increment();
1748 Handle<Object> result = RegExpImpl::Exec(regexp, 1748 Handle<Object> result = RegExpImpl::Exec(regexp,
1749 subject, 1749 subject,
1750 index, 1750 index,
1751 last_match_info, 1751 last_match_info);
1752 isolate->zone());
1753 if (result.is_null()) return Failure::Exception(); 1752 if (result.is_null()) return Failure::Exception();
1754 return *result; 1753 return *result;
1755 } 1754 }
1756 1755
1757 1756
1758 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpConstructResult) { 1757 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpConstructResult) {
1759 ASSERT(args.length() == 3); 1758 ASSERT(args.length() == 3);
1760 CONVERT_SMI_ARG_CHECKED(elements_count, 0); 1759 CONVERT_SMI_ARG_CHECKED(elements_count, 0);
1761 if (elements_count < 0 || 1760 if (elements_count < 0 ||
1762 elements_count > FixedArray::kMaxLength || 1761 elements_count > FixedArray::kMaxLength ||
(...skipping 1313 matching lines...) Expand 10 before | Expand all | Expand 10 after
3076 HandleScope handles(isolate); 3075 HandleScope handles(isolate);
3077 3076
3078 int length = subject->length(); 3077 int length = subject->length();
3079 Handle<String> subject_handle(subject); 3078 Handle<String> subject_handle(subject);
3080 Handle<JSRegExp> regexp_handle(regexp); 3079 Handle<JSRegExp> regexp_handle(regexp);
3081 Handle<String> replacement_handle(replacement); 3080 Handle<String> replacement_handle(replacement);
3082 Handle<JSArray> last_match_info_handle(last_match_info); 3081 Handle<JSArray> last_match_info_handle(last_match_info);
3083 Handle<Object> match = RegExpImpl::Exec(regexp_handle, 3082 Handle<Object> match = RegExpImpl::Exec(regexp_handle,
3084 subject_handle, 3083 subject_handle,
3085 0, 3084 0,
3086 last_match_info_handle, 3085 last_match_info_handle);
3087 isolate->zone());
3088 if (match.is_null()) { 3086 if (match.is_null()) {
3089 return Failure::Exception(); 3087 return Failure::Exception();
3090 } 3088 }
3091 if (match->IsNull()) { 3089 if (match->IsNull()) {
3092 return *subject_handle; 3090 return *subject_handle;
3093 } 3091 }
3094 3092
3095 int capture_count = regexp_handle->CaptureCount(); 3093 int capture_count = regexp_handle->CaptureCount();
3096 3094
3097 // CompiledReplacement uses zone allocation. 3095 // CompiledReplacement uses zone allocation.
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
3178 // Continue from where the match ended, unless it was an empty match. 3176 // Continue from where the match ended, unless it was an empty match.
3179 int next = end; 3177 int next = end;
3180 if (start == end) { 3178 if (start == end) {
3181 next = end + 1; 3179 next = end + 1;
3182 if (next > length) break; 3180 if (next > length) break;
3183 } 3181 }
3184 3182
3185 match = RegExpImpl::Exec(regexp_handle, 3183 match = RegExpImpl::Exec(regexp_handle,
3186 subject_handle, 3184 subject_handle,
3187 next, 3185 next,
3188 last_match_info_handle, 3186 last_match_info_handle);
3189 isolate->zone());
3190 if (match.is_null()) { 3187 if (match.is_null()) {
3191 return Failure::Exception(); 3188 return Failure::Exception();
3192 } 3189 }
3193 matched = !match->IsNull(); 3190 matched = !match->IsNull();
3194 } while (matched); 3191 } while (matched);
3195 3192
3196 if (prev < length) { 3193 if (prev < length) {
3197 builder.AddSubjectSlice(prev, length); 3194 builder.AddSubjectSlice(prev, length);
3198 } 3195 }
3199 3196
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3235 regexp_handle, 3232 regexp_handle,
3236 empty_string_handle, 3233 empty_string_handle,
3237 last_match_info_handle, 3234 last_match_info_handle,
3238 zone); 3235 zone);
3239 } 3236 }
3240 } 3237 }
3241 3238
3242 Handle<Object> match = RegExpImpl::Exec(regexp_handle, 3239 Handle<Object> match = RegExpImpl::Exec(regexp_handle,
3243 subject_handle, 3240 subject_handle,
3244 0, 3241 0,
3245 last_match_info_handle, 3242 last_match_info_handle);
3246 isolate->zone());
3247 if (match.is_null()) return Failure::Exception(); 3243 if (match.is_null()) return Failure::Exception();
3248 if (match->IsNull()) return *subject_handle; 3244 if (match->IsNull()) return *subject_handle;
3249 3245
3250 ASSERT(last_match_info_handle->HasFastObjectElements()); 3246 ASSERT(last_match_info_handle->HasFastObjectElements());
3251 3247
3252 int start, end; 3248 int start, end;
3253 { 3249 {
3254 AssertNoAllocation match_info_array_is_not_in_a_handle; 3250 AssertNoAllocation match_info_array_is_not_in_a_handle;
3255 FixedArray* match_info_array = 3251 FixedArray* match_info_array =
3256 FixedArray::cast(last_match_info_handle->elements()); 3252 FixedArray::cast(last_match_info_handle->elements());
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
3310 prev = end; 3306 prev = end;
3311 next = end; 3307 next = end;
3312 // Continue from where the match ended, unless it was an empty match. 3308 // Continue from where the match ended, unless it was an empty match.
3313 if (start == end) { 3309 if (start == end) {
3314 next++; 3310 next++;
3315 if (next > length) break; 3311 if (next > length) break;
3316 } 3312 }
3317 match = RegExpImpl::Exec(regexp_handle, 3313 match = RegExpImpl::Exec(regexp_handle,
3318 subject_handle, 3314 subject_handle,
3319 next, 3315 next,
3320 last_match_info_handle, 3316 last_match_info_handle);
3321 isolate->zone());
3322 if (match.is_null()) return Failure::Exception(); 3317 if (match.is_null()) return Failure::Exception();
3323 if (match->IsNull()) break; 3318 if (match->IsNull()) break;
3324 3319
3325 ASSERT(last_match_info_handle->HasFastObjectElements()); 3320 ASSERT(last_match_info_handle->HasFastObjectElements());
3326 HandleScope loop_scope(isolate); 3321 HandleScope loop_scope(isolate);
3327 { 3322 {
3328 AssertNoAllocation match_info_array_is_not_in_a_handle; 3323 AssertNoAllocation match_info_array_is_not_in_a_handle;
3329 FixedArray* match_info_array = 3324 FixedArray* match_info_array =
3330 FixedArray::cast(last_match_info_handle->elements()); 3325 FixedArray::cast(last_match_info_handle->elements());
3331 start = RegExpImpl::GetCapture(match_info_array, 0); 3326 start = RegExpImpl::GetCapture(match_info_array, 0);
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
3726 3721
3727 3722
3728 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringMatch) { 3723 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringMatch) {
3729 ASSERT_EQ(3, args.length()); 3724 ASSERT_EQ(3, args.length());
3730 3725
3731 CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); 3726 CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
3732 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1); 3727 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
3733 CONVERT_ARG_HANDLE_CHECKED(JSArray, regexp_info, 2); 3728 CONVERT_ARG_HANDLE_CHECKED(JSArray, regexp_info, 2);
3734 HandleScope handles; 3729 HandleScope handles;
3735 3730
3736 Handle<Object> match = RegExpImpl::Exec(regexp, subject, 0, regexp_info, 3731 Handle<Object> match = RegExpImpl::Exec(regexp, subject, 0, regexp_info);
3737 isolate->zone());
3738 3732
3739 if (match.is_null()) { 3733 if (match.is_null()) {
3740 return Failure::Exception(); 3734 return Failure::Exception();
3741 } 3735 }
3742 if (match->IsNull()) { 3736 if (match->IsNull()) {
3743 return isolate->heap()->null_value(); 3737 return isolate->heap()->null_value();
3744 } 3738 }
3745 int length = subject->length(); 3739 int length = subject->length();
3746 3740
3747 Zone* zone = isolate->zone(); 3741 Zone* zone = isolate->zone();
3748 ZoneScope zone_space(isolate, DELETE_ON_EXIT); 3742 ZoneScope zone_space(isolate, DELETE_ON_EXIT);
3749 ZoneList<int> offsets(8, zone); 3743 ZoneList<int> offsets(8, zone);
3750 int start; 3744 int start;
3751 int end; 3745 int end;
3752 do { 3746 do {
3753 { 3747 {
3754 AssertNoAllocation no_alloc; 3748 AssertNoAllocation no_alloc;
3755 FixedArray* elements = FixedArray::cast(regexp_info->elements()); 3749 FixedArray* elements = FixedArray::cast(regexp_info->elements());
3756 start = Smi::cast(elements->get(RegExpImpl::kFirstCapture))->value(); 3750 start = Smi::cast(elements->get(RegExpImpl::kFirstCapture))->value();
3757 end = Smi::cast(elements->get(RegExpImpl::kFirstCapture + 1))->value(); 3751 end = Smi::cast(elements->get(RegExpImpl::kFirstCapture + 1))->value();
3758 } 3752 }
3759 offsets.Add(start, zone); 3753 offsets.Add(start, zone);
3760 offsets.Add(end, zone); 3754 offsets.Add(end, zone);
3761 if (start == end) if (++end > length) break; 3755 if (start == end) if (++end > length) break;
3762 match = RegExpImpl::Exec(regexp, subject, end, regexp_info, 3756 match = RegExpImpl::Exec(regexp, subject, end, regexp_info);
3763 isolate->zone());
3764 if (match.is_null()) { 3757 if (match.is_null()) {
3765 return Failure::Exception(); 3758 return Failure::Exception();
3766 } 3759 }
3767 } while (!match->IsNull()); 3760 } while (!match->IsNull());
3768 int matches = offsets.length() / 2; 3761 int matches = offsets.length() / 2;
3769 Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches); 3762 Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches);
3770 Handle<String> substring = isolate->factory()-> 3763 Handle<String> substring = isolate->factory()->
3771 NewSubString(subject, offsets.at(0), offsets.at(1)); 3764 NewSubString(subject, offsets.at(0), offsets.at(1));
3772 elements->set(0, *substring); 3765 elements->set(0, *substring);
3773 for (int i = 1; i < matches ; i++) { 3766 for (int i = 1; i < matches ; i++) {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
3851 Isolate* isolate, 3844 Isolate* isolate,
3852 Handle<String> subject, 3845 Handle<String> subject,
3853 Handle<JSRegExp> regexp, 3846 Handle<JSRegExp> regexp,
3854 Handle<JSArray> last_match_array, 3847 Handle<JSArray> last_match_array,
3855 FixedArrayBuilder* builder) { 3848 FixedArrayBuilder* builder) {
3856 ASSERT(subject->IsFlat()); 3849 ASSERT(subject->IsFlat());
3857 ASSERT(regexp->CaptureCount() == 0); 3850 ASSERT(regexp->CaptureCount() == 0);
3858 int match_start = -1; 3851 int match_start = -1;
3859 int match_end = 0; 3852 int match_end = 0;
3860 int pos = 0; 3853 int pos = 0;
3861 int registers_per_match = RegExpImpl::IrregexpPrepare(regexp, subject, 3854 int registers_per_match = RegExpImpl::IrregexpPrepare(regexp, subject);
3862 isolate->zone());
3863 if (registers_per_match < 0) return RegExpImpl::RE_EXCEPTION; 3855 if (registers_per_match < 0) return RegExpImpl::RE_EXCEPTION;
3864 3856
3865 int max_matches; 3857 int max_matches;
3866 int num_registers = RegExpImpl::GlobalOffsetsVectorSize(regexp, 3858 int num_registers = RegExpImpl::GlobalOffsetsVectorSize(regexp,
3867 registers_per_match, 3859 registers_per_match,
3868 &max_matches); 3860 &max_matches);
3869 OffsetsVector registers(num_registers, isolate); 3861 OffsetsVector registers(num_registers, isolate);
3870 Vector<int32_t> register_vector(registers.vector(), registers.length()); 3862 Vector<int32_t> register_vector(registers.vector(), registers.length());
3871 int subject_length = subject->length(); 3863 int subject_length = subject->length();
3872 bool first = true; 3864 bool first = true;
3873 for (;;) { // Break on failure, return on exception. 3865 for (;;) { // Break on failure, return on exception.
3874 int num_matches = RegExpImpl::IrregexpExecRaw(regexp, 3866 int num_matches = RegExpImpl::IrregexpExecRaw(regexp,
3875 subject, 3867 subject,
3876 pos, 3868 pos,
3877 register_vector, 3869 register_vector);
3878 isolate->zone());
3879 if (num_matches > 0) { 3870 if (num_matches > 0) {
3880 for (int match_index = 0; match_index < num_matches; match_index++) { 3871 for (int match_index = 0; match_index < num_matches; match_index++) {
3881 int32_t* current_match = &register_vector[match_index * 2]; 3872 int32_t* current_match = &register_vector[match_index * 2];
3882 match_start = current_match[0]; 3873 match_start = current_match[0];
3883 builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch); 3874 builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
3884 if (match_end < match_start) { 3875 if (match_end < match_start) {
3885 ReplacementStringBuilder::AddSubjectSlice(builder, 3876 ReplacementStringBuilder::AddSubjectSlice(builder,
3886 match_end, 3877 match_end,
3887 match_start); 3878 match_start);
3888 } 3879 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
3938 // Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain 3929 // Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain
3939 // separate last match info. See comment on that function. 3930 // separate last match info. See comment on that function.
3940 static int SearchRegExpMultiple( 3931 static int SearchRegExpMultiple(
3941 Isolate* isolate, 3932 Isolate* isolate,
3942 Handle<String> subject, 3933 Handle<String> subject,
3943 Handle<JSRegExp> regexp, 3934 Handle<JSRegExp> regexp,
3944 Handle<JSArray> last_match_array, 3935 Handle<JSArray> last_match_array,
3945 FixedArrayBuilder* builder) { 3936 FixedArrayBuilder* builder) {
3946 3937
3947 ASSERT(subject->IsFlat()); 3938 ASSERT(subject->IsFlat());
3948 int registers_per_match = RegExpImpl::IrregexpPrepare(regexp, subject, 3939 int registers_per_match = RegExpImpl::IrregexpPrepare(regexp, subject);
3949 isolate->zone());
3950 if (registers_per_match < 0) return RegExpImpl::RE_EXCEPTION; 3940 if (registers_per_match < 0) return RegExpImpl::RE_EXCEPTION;
3951 3941
3952 int max_matches; 3942 int max_matches;
3953 int num_registers = RegExpImpl::GlobalOffsetsVectorSize(regexp, 3943 int num_registers = RegExpImpl::GlobalOffsetsVectorSize(regexp,
3954 registers_per_match, 3944 registers_per_match,
3955 &max_matches); 3945 &max_matches);
3956 OffsetsVector registers(num_registers, isolate); 3946 OffsetsVector registers(num_registers, isolate);
3957 Vector<int32_t> register_vector(registers.vector(), registers.length()); 3947 Vector<int32_t> register_vector(registers.vector(), registers.length());
3958 3948
3959 int num_matches = RegExpImpl::IrregexpExecRaw(regexp, 3949 int num_matches = RegExpImpl::IrregexpExecRaw(regexp,
3960 subject, 3950 subject,
3961 0, 3951 0,
3962 register_vector, 3952 register_vector);
3963 isolate->zone());
3964 3953
3965 int capture_count = regexp->CaptureCount(); 3954 int capture_count = regexp->CaptureCount();
3966 int subject_length = subject->length(); 3955 int subject_length = subject->length();
3967 3956
3968 // Position to search from. 3957 // Position to search from.
3969 int pos = 0; 3958 int pos = 0;
3970 // End of previous match. Differs from pos if match was empty. 3959 // End of previous match. Differs from pos if match was empty.
3971 int match_end = 0; 3960 int match_end = 0;
3972 bool first = true; 3961 bool first = true;
3973 3962
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
4039 } else { 4028 } else {
4040 pos = match_end + 1; 4029 pos = match_end + 1;
4041 if (pos > subject_length) { 4030 if (pos > subject_length) {
4042 break; 4031 break;
4043 } 4032 }
4044 } 4033 }
4045 4034
4046 num_matches = RegExpImpl::IrregexpExecRaw(regexp, 4035 num_matches = RegExpImpl::IrregexpExecRaw(regexp,
4047 subject, 4036 subject,
4048 pos, 4037 pos,
4049 register_vector, 4038 register_vector);
4050 isolate->zone());
4051 } while (num_matches > 0); 4039 } while (num_matches > 0);
4052 4040
4053 if (num_matches != RegExpImpl::RE_EXCEPTION) { 4041 if (num_matches != RegExpImpl::RE_EXCEPTION) {
4054 // Finished matching, with at least one match. 4042 // Finished matching, with at least one match.
4055 if (match_end < subject_length) { 4043 if (match_end < subject_length) {
4056 ReplacementStringBuilder::AddSubjectSlice(builder, 4044 ReplacementStringBuilder::AddSubjectSlice(builder,
4057 match_end, 4045 match_end,
4058 subject_length); 4046 subject_length);
4059 } 4047 }
4060 4048
(...skipping 9534 matching lines...) Expand 10 before | Expand all | Expand 10 after
13595 // Handle last resort GC and make sure to allow future allocations 13583 // Handle last resort GC and make sure to allow future allocations
13596 // to grow the heap without causing GCs (if possible). 13584 // to grow the heap without causing GCs (if possible).
13597 isolate->counters()->gc_last_resort_from_js()->Increment(); 13585 isolate->counters()->gc_last_resort_from_js()->Increment();
13598 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 13586 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
13599 "Runtime::PerformGC"); 13587 "Runtime::PerformGC");
13600 } 13588 }
13601 } 13589 }
13602 13590
13603 13591
13604 } } // namespace v8::internal 13592 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/regexp-macro-assembler-irregexp.cc ('k') | test/cctest/test-regexp.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698