| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/runtime/runtime-utils.h" | 5 #include "src/runtime/runtime-utils.h" |
| 6 | 6 |
| 7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
| 8 #include "src/conversions-inl.h" | 8 #include "src/conversions-inl.h" |
| 9 #include "src/isolate-inl.h" | 9 #include "src/isolate-inl.h" |
| 10 #include "src/messages.h" | 10 #include "src/messages.h" |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 limit, zone); | 379 limit, zone); |
| 380 } else { | 380 } else { |
| 381 FindStringIndices(isolate, subject_vector, pattern_vector, indices, | 381 FindStringIndices(isolate, subject_vector, pattern_vector, indices, |
| 382 limit, zone); | 382 limit, zone); |
| 383 } | 383 } |
| 384 } | 384 } |
| 385 } | 385 } |
| 386 } | 386 } |
| 387 } | 387 } |
| 388 | 388 |
| 389 | |
| 390 template <typename ResultSeqString> | 389 template <typename ResultSeqString> |
| 391 MUST_USE_RESULT static Object* StringReplaceGlobalAtomRegExpWithString( | 390 MUST_USE_RESULT static Object* StringReplaceGlobalAtomRegExpWithString( |
| 392 Isolate* isolate, Handle<String> subject, Handle<JSRegExp> pattern_regexp, | 391 Isolate* isolate, Handle<String> subject, Handle<JSRegExp> pattern_regexp, |
| 393 Handle<String> replacement, Handle<JSArray> last_match_info) { | 392 Handle<String> replacement, Handle<JSObject> last_match_info) { |
| 394 DCHECK(subject->IsFlat()); | 393 DCHECK(subject->IsFlat()); |
| 395 DCHECK(replacement->IsFlat()); | 394 DCHECK(replacement->IsFlat()); |
| 396 | 395 |
| 397 ZoneScope zone_scope(isolate->runtime_zone()); | 396 ZoneScope zone_scope(isolate->runtime_zone()); |
| 398 ZoneList<int> indices(8, zone_scope.zone()); | 397 ZoneList<int> indices(8, zone_scope.zone()); |
| 399 DCHECK_EQ(JSRegExp::ATOM, pattern_regexp->TypeTag()); | 398 DCHECK_EQ(JSRegExp::ATOM, pattern_regexp->TypeTag()); |
| 400 String* pattern = | 399 String* pattern = |
| 401 String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex)); | 400 String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex)); |
| 402 int subject_len = subject->length(); | 401 int subject_len = subject->length(); |
| 403 int pattern_len = pattern->length(); | 402 int pattern_len = pattern->length(); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 subject_len); | 457 subject_len); |
| 459 } | 458 } |
| 460 | 459 |
| 461 int32_t match_indices[] = {indices.at(matches - 1), | 460 int32_t match_indices[] = {indices.at(matches - 1), |
| 462 indices.at(matches - 1) + pattern_len}; | 461 indices.at(matches - 1) + pattern_len}; |
| 463 RegExpImpl::SetLastMatchInfo(last_match_info, subject, 0, match_indices); | 462 RegExpImpl::SetLastMatchInfo(last_match_info, subject, 0, match_indices); |
| 464 | 463 |
| 465 return *result; | 464 return *result; |
| 466 } | 465 } |
| 467 | 466 |
| 468 | |
| 469 MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithString( | 467 MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithString( |
| 470 Isolate* isolate, Handle<String> subject, Handle<JSRegExp> regexp, | 468 Isolate* isolate, Handle<String> subject, Handle<JSRegExp> regexp, |
| 471 Handle<String> replacement, Handle<JSArray> last_match_info) { | 469 Handle<String> replacement, Handle<JSObject> last_match_info) { |
| 472 DCHECK(subject->IsFlat()); | 470 DCHECK(subject->IsFlat()); |
| 473 DCHECK(replacement->IsFlat()); | 471 DCHECK(replacement->IsFlat()); |
| 474 | 472 |
| 475 int capture_count = regexp->CaptureCount(); | 473 int capture_count = regexp->CaptureCount(); |
| 476 int subject_length = subject->length(); | 474 int subject_length = subject->length(); |
| 477 | 475 |
| 478 // CompiledReplacement uses zone allocation. | 476 // CompiledReplacement uses zone allocation. |
| 479 ZoneScope zone_scope(isolate->runtime_zone()); | 477 ZoneScope zone_scope(isolate->runtime_zone()); |
| 480 CompiledReplacement compiled_replacement(zone_scope.zone()); | 478 CompiledReplacement compiled_replacement(zone_scope.zone()); |
| 481 bool simple_replace = | 479 bool simple_replace = |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 540 builder.EnsureCapacity(2); | 538 builder.EnsureCapacity(2); |
| 541 builder.AddSubjectSlice(prev, subject_length); | 539 builder.AddSubjectSlice(prev, subject_length); |
| 542 } | 540 } |
| 543 | 541 |
| 544 RegExpImpl::SetLastMatchInfo(last_match_info, subject, capture_count, | 542 RegExpImpl::SetLastMatchInfo(last_match_info, subject, capture_count, |
| 545 global_cache.LastSuccessfulMatch()); | 543 global_cache.LastSuccessfulMatch()); |
| 546 | 544 |
| 547 RETURN_RESULT_OR_FAILURE(isolate, builder.ToString()); | 545 RETURN_RESULT_OR_FAILURE(isolate, builder.ToString()); |
| 548 } | 546 } |
| 549 | 547 |
| 550 | |
| 551 template <typename ResultSeqString> | 548 template <typename ResultSeqString> |
| 552 MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithEmptyString( | 549 MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithEmptyString( |
| 553 Isolate* isolate, Handle<String> subject, Handle<JSRegExp> regexp, | 550 Isolate* isolate, Handle<String> subject, Handle<JSRegExp> regexp, |
| 554 Handle<JSArray> last_match_info) { | 551 Handle<JSObject> last_match_info) { |
| 555 DCHECK(subject->IsFlat()); | 552 DCHECK(subject->IsFlat()); |
| 556 | 553 |
| 557 // Shortcut for simple non-regexp global replacements | 554 // Shortcut for simple non-regexp global replacements |
| 558 if (regexp->TypeTag() == JSRegExp::ATOM) { | 555 if (regexp->TypeTag() == JSRegExp::ATOM) { |
| 559 Handle<String> empty_string = isolate->factory()->empty_string(); | 556 Handle<String> empty_string = isolate->factory()->empty_string(); |
| 560 if (subject->IsOneByteRepresentation()) { | 557 if (subject->IsOneByteRepresentation()) { |
| 561 return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>( | 558 return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>( |
| 562 isolate, subject, regexp, empty_string, last_match_info); | 559 isolate, subject, regexp, empty_string, last_match_info); |
| 563 } else { | 560 } else { |
| 564 return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>( | 561 return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>( |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 647 } | 644 } |
| 648 | 645 |
| 649 | 646 |
| 650 RUNTIME_FUNCTION(Runtime_StringReplaceGlobalRegExpWithString) { | 647 RUNTIME_FUNCTION(Runtime_StringReplaceGlobalRegExpWithString) { |
| 651 HandleScope scope(isolate); | 648 HandleScope scope(isolate); |
| 652 DCHECK(args.length() == 4); | 649 DCHECK(args.length() == 4); |
| 653 | 650 |
| 654 CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); | 651 CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); |
| 655 CONVERT_ARG_HANDLE_CHECKED(String, replacement, 2); | 652 CONVERT_ARG_HANDLE_CHECKED(String, replacement, 2); |
| 656 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1); | 653 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1); |
| 657 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3); | 654 CONVERT_ARG_HANDLE_CHECKED(JSObject, last_match_info, 3); |
| 658 | 655 |
| 659 CHECK(regexp->GetFlags() & JSRegExp::kGlobal); | 656 CHECK(regexp->GetFlags() & JSRegExp::kGlobal); |
| 660 CHECK(last_match_info->HasFastObjectElements()); | 657 CHECK(last_match_info->HasFastObjectElements()); |
| 661 | 658 |
| 662 subject = String::Flatten(subject); | 659 subject = String::Flatten(subject); |
| 663 | 660 |
| 664 if (replacement->length() == 0) { | 661 if (replacement->length() == 0) { |
| 665 if (subject->HasOnlyOneByteChars()) { | 662 if (subject->HasOnlyOneByteChars()) { |
| 666 return StringReplaceGlobalRegExpWithEmptyString<SeqOneByteString>( | 663 return StringReplaceGlobalRegExpWithEmptyString<SeqOneByteString>( |
| 667 isolate, subject, regexp, last_match_info); | 664 isolate, subject, regexp, last_match_info); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 764 return *result; | 761 return *result; |
| 765 } | 762 } |
| 766 | 763 |
| 767 | 764 |
| 768 RUNTIME_FUNCTION(Runtime_RegExpExec) { | 765 RUNTIME_FUNCTION(Runtime_RegExpExec) { |
| 769 HandleScope scope(isolate); | 766 HandleScope scope(isolate); |
| 770 DCHECK(args.length() == 4); | 767 DCHECK(args.length() == 4); |
| 771 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); | 768 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); |
| 772 CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); | 769 CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); |
| 773 CONVERT_INT32_ARG_CHECKED(index, 2); | 770 CONVERT_INT32_ARG_CHECKED(index, 2); |
| 774 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3); | 771 CONVERT_ARG_HANDLE_CHECKED(JSObject, last_match_info, 3); |
| 775 // Due to the way the JS calls are constructed this must be less than the | 772 // Due to the way the JS calls are constructed this must be less than the |
| 776 // length of a string, i.e. it is always a Smi. We check anyway for security. | 773 // length of a string, i.e. it is always a Smi. We check anyway for security. |
| 777 CHECK(index >= 0); | 774 CHECK(index >= 0); |
| 778 CHECK(index <= subject->length()); | 775 CHECK(index <= subject->length()); |
| 779 isolate->counters()->regexp_entry_runtime()->Increment(); | 776 isolate->counters()->regexp_entry_runtime()->Increment(); |
| 780 RETURN_RESULT_OR_FAILURE( | 777 RETURN_RESULT_OR_FAILURE( |
| 781 isolate, RegExpImpl::Exec(regexp, subject, index, last_match_info)); | 778 isolate, RegExpImpl::Exec(regexp, subject, index, last_match_info)); |
| 782 } | 779 } |
| 783 | 780 |
| 784 | 781 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 831 | 828 |
| 832 return *regexp; | 829 return *regexp; |
| 833 } | 830 } |
| 834 | 831 |
| 835 | 832 |
| 836 // Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain | 833 // Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain |
| 837 // separate last match info. See comment on that function. | 834 // separate last match info. See comment on that function. |
| 838 template <bool has_capture> | 835 template <bool has_capture> |
| 839 static Object* SearchRegExpMultiple(Isolate* isolate, Handle<String> subject, | 836 static Object* SearchRegExpMultiple(Isolate* isolate, Handle<String> subject, |
| 840 Handle<JSRegExp> regexp, | 837 Handle<JSRegExp> regexp, |
| 841 Handle<JSArray> last_match_array, | 838 Handle<JSObject> last_match_array, |
| 842 Handle<JSArray> result_array) { | 839 Handle<JSArray> result_array) { |
| 843 DCHECK(subject->IsFlat()); | 840 DCHECK(subject->IsFlat()); |
| 844 DCHECK_NE(has_capture, regexp->CaptureCount() == 0); | 841 DCHECK_NE(has_capture, regexp->CaptureCount() == 0); |
| 845 | 842 |
| 846 int capture_count = regexp->CaptureCount(); | 843 int capture_count = regexp->CaptureCount(); |
| 847 int subject_length = subject->length(); | 844 int subject_length = subject->length(); |
| 848 | 845 |
| 849 static const int kMinLengthToCache = 0x1000; | 846 static const int kMinLengthToCache = 0x1000; |
| 850 | 847 |
| 851 if (subject_length > kMinLengthToCache) { | 848 if (subject_length > kMinLengthToCache) { |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 981 | 978 |
| 982 // This is only called for StringReplaceGlobalRegExpWithFunction. This sets | 979 // This is only called for StringReplaceGlobalRegExpWithFunction. This sets |
| 983 // lastMatchInfoOverride to maintain the last match info, so we don't need to | 980 // lastMatchInfoOverride to maintain the last match info, so we don't need to |
| 984 // set any other last match array info. | 981 // set any other last match array info. |
| 985 RUNTIME_FUNCTION(Runtime_RegExpExecMultiple) { | 982 RUNTIME_FUNCTION(Runtime_RegExpExecMultiple) { |
| 986 HandleScope handles(isolate); | 983 HandleScope handles(isolate); |
| 987 DCHECK(args.length() == 4); | 984 DCHECK(args.length() == 4); |
| 988 | 985 |
| 989 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); | 986 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); |
| 990 CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); | 987 CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); |
| 991 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2); | 988 CONVERT_ARG_HANDLE_CHECKED(JSObject, last_match_info, 2); |
| 992 CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3); | 989 CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3); |
| 993 CHECK(last_match_info->HasFastObjectElements()); | 990 CHECK(last_match_info->HasFastObjectElements()); |
| 994 CHECK(result_array->HasFastObjectElements()); | 991 CHECK(result_array->HasFastObjectElements()); |
| 995 | 992 |
| 996 subject = String::Flatten(subject); | 993 subject = String::Flatten(subject); |
| 997 CHECK(regexp->GetFlags() & JSRegExp::kGlobal); | 994 CHECK(regexp->GetFlags() & JSRegExp::kGlobal); |
| 998 | 995 |
| 999 if (regexp->CaptureCount() == 0) { | 996 if (regexp->CaptureCount() == 0) { |
| 1000 return SearchRegExpMultiple<false>(isolate, subject, regexp, | 997 return SearchRegExpMultiple<false>(isolate, subject, regexp, |
| 1001 last_match_info, result_array); | 998 last_match_info, result_array); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1016 | 1013 |
| 1017 | 1014 |
| 1018 RUNTIME_FUNCTION(Runtime_IsRegExp) { | 1015 RUNTIME_FUNCTION(Runtime_IsRegExp) { |
| 1019 SealHandleScope shs(isolate); | 1016 SealHandleScope shs(isolate); |
| 1020 DCHECK(args.length() == 1); | 1017 DCHECK(args.length() == 1); |
| 1021 CONVERT_ARG_CHECKED(Object, obj, 0); | 1018 CONVERT_ARG_CHECKED(Object, obj, 0); |
| 1022 return isolate->heap()->ToBoolean(obj->IsJSRegExp()); | 1019 return isolate->heap()->ToBoolean(obj->IsJSRegExp()); |
| 1023 } | 1020 } |
| 1024 } // namespace internal | 1021 } // namespace internal |
| 1025 } // namespace v8 | 1022 } // namespace v8 |
| OLD | NEW |