OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/objects.h" | 5 #include "src/objects.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 #include <iomanip> | 8 #include <iomanip> |
9 #include <memory> | 9 #include <memory> |
10 #include <sstream> | 10 #include <sstream> |
(...skipping 11634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11645 if (search_content.IsOneByte()) { | 11645 if (search_content.IsOneByte()) { |
11646 Vector<const uint8_t> pat_vector = search_content.ToOneByteVector(); | 11646 Vector<const uint8_t> pat_vector = search_content.ToOneByteVector(); |
11647 return SearchString<const uint8_t>(isolate, receiver_content, pat_vector, | 11647 return SearchString<const uint8_t>(isolate, receiver_content, pat_vector, |
11648 start_index); | 11648 start_index); |
11649 } | 11649 } |
11650 Vector<const uc16> pat_vector = search_content.ToUC16Vector(); | 11650 Vector<const uc16> pat_vector = search_content.ToUC16Vector(); |
11651 return SearchString<const uc16>(isolate, receiver_content, pat_vector, | 11651 return SearchString<const uc16>(isolate, receiver_content, pat_vector, |
11652 start_index); | 11652 start_index); |
11653 } | 11653 } |
11654 | 11654 |
| 11655 MaybeHandle<String> String::GetSubstitution(Isolate* isolate, Match* match, |
| 11656 Handle<String> replacement) { |
| 11657 Factory* factory = isolate->factory(); |
| 11658 |
| 11659 const int replacement_length = replacement->length(); |
| 11660 const int captures_length = match->CaptureCount(); |
| 11661 |
| 11662 replacement = String::Flatten(replacement); |
| 11663 |
| 11664 Handle<String> dollar_string = |
| 11665 factory->LookupSingleCharacterStringFromCode('$'); |
| 11666 int next = String::IndexOf(isolate, replacement, dollar_string, 0); |
| 11667 if (next < 0) { |
| 11668 return replacement; |
| 11669 } |
| 11670 |
| 11671 IncrementalStringBuilder builder(isolate); |
| 11672 |
| 11673 if (next > 0) { |
| 11674 builder.AppendString(factory->NewSubString(replacement, 0, next)); |
| 11675 } |
| 11676 |
| 11677 while (true) { |
| 11678 int pos = next + 1; |
| 11679 if (pos < replacement_length) { |
| 11680 const uint16_t peek = replacement->Get(pos); |
| 11681 if (peek == '$') { // $$ |
| 11682 pos++; |
| 11683 builder.AppendCharacter('$'); |
| 11684 } else if (peek == '&') { // $& - match |
| 11685 pos++; |
| 11686 builder.AppendString(match->GetMatch()); |
| 11687 } else if (peek == '`') { // $` - prefix |
| 11688 pos++; |
| 11689 builder.AppendString(match->GetPrefix()); |
| 11690 } else if (peek == '\'') { // $' - suffix |
| 11691 pos++; |
| 11692 builder.AppendString(match->GetSuffix()); |
| 11693 } else if (peek >= '0' && peek <= '9') { |
| 11694 // Valid indices are $1 .. $9, $01 .. $09 and $10 .. $99 |
| 11695 int scaled_index = (peek - '0'); |
| 11696 int advance = 1; |
| 11697 |
| 11698 if (pos + 1 < replacement_length) { |
| 11699 const uint16_t next_peek = replacement->Get(pos + 1); |
| 11700 if (next_peek >= '0' && next_peek <= '9') { |
| 11701 const int new_scaled_index = scaled_index * 10 + (next_peek - '0'); |
| 11702 if (new_scaled_index < captures_length) { |
| 11703 scaled_index = new_scaled_index; |
| 11704 advance = 2; |
| 11705 } |
| 11706 } |
| 11707 } |
| 11708 |
| 11709 if (scaled_index != 0 && scaled_index < captures_length) { |
| 11710 bool capture_exists; |
| 11711 Handle<String> capture; |
| 11712 ASSIGN_RETURN_ON_EXCEPTION( |
| 11713 isolate, capture, |
| 11714 match->GetCapture(scaled_index, &capture_exists), String); |
| 11715 if (capture_exists) builder.AppendString(capture); |
| 11716 pos += advance; |
| 11717 } else { |
| 11718 builder.AppendCharacter('$'); |
| 11719 } |
| 11720 } else { |
| 11721 builder.AppendCharacter('$'); |
| 11722 } |
| 11723 } else { |
| 11724 builder.AppendCharacter('$'); |
| 11725 } |
| 11726 |
| 11727 // Go the the next $ in the replacement. |
| 11728 next = String::IndexOf(isolate, replacement, dollar_string, pos); |
| 11729 |
| 11730 // Return if there are no more $ characters in the replacement. If we |
| 11731 // haven't reached the end, we need to append the suffix. |
| 11732 if (next < 0) { |
| 11733 if (pos < replacement_length) { |
| 11734 builder.AppendString( |
| 11735 factory->NewSubString(replacement, pos, replacement_length)); |
| 11736 } |
| 11737 return builder.Finish(); |
| 11738 } |
| 11739 |
| 11740 // Append substring between the previous and the next $ character. |
| 11741 if (next > pos) { |
| 11742 builder.AppendString(factory->NewSubString(replacement, pos, next)); |
| 11743 } |
| 11744 } |
| 11745 |
| 11746 UNREACHABLE(); |
| 11747 return MaybeHandle<String>(); |
| 11748 } |
| 11749 |
11655 namespace { // for String.Prototype.lastIndexOf | 11750 namespace { // for String.Prototype.lastIndexOf |
11656 | 11751 |
11657 template <typename schar, typename pchar> | 11752 template <typename schar, typename pchar> |
11658 int StringMatchBackwards(Vector<const schar> subject, | 11753 int StringMatchBackwards(Vector<const schar> subject, |
11659 Vector<const pchar> pattern, int idx) { | 11754 Vector<const pchar> pattern, int idx) { |
11660 int pattern_length = pattern.length(); | 11755 int pattern_length = pattern.length(); |
11661 DCHECK(pattern_length >= 1); | 11756 DCHECK(pattern_length >= 1); |
11662 DCHECK(idx + pattern_length <= subject.length()); | 11757 DCHECK(idx + pattern_length <= subject.length()); |
11663 | 11758 |
11664 if (sizeof(schar) == 1 && sizeof(pchar) > 1) { | 11759 if (sizeof(schar) == 1 && sizeof(pchar) > 1) { |
(...skipping 8419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
20084 ns, Accessors::ModuleNamespaceEntryInfo(isolate, name, attr)) | 20179 ns, Accessors::ModuleNamespaceEntryInfo(isolate, name, attr)) |
20085 .Check(); | 20180 .Check(); |
20086 } | 20181 } |
20087 JSObject::PreventExtensions(ns, THROW_ON_ERROR).ToChecked(); | 20182 JSObject::PreventExtensions(ns, THROW_ON_ERROR).ToChecked(); |
20088 | 20183 |
20089 return ns; | 20184 return ns; |
20090 } | 20185 } |
20091 | 20186 |
20092 } // namespace internal | 20187 } // namespace internal |
20093 } // namespace v8 | 20188 } // namespace v8 |
OLD | NEW |