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 1730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 = ®ister_vector[match_index * 2]; | 3872 int32_t* current_match = ®ister_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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |