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 |