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/regexp/jsregexp-inl.h" | 8 #include "src/regexp/jsregexp-inl.h" |
9 #include "src/string-builder.h" | 9 #include "src/string-builder.h" |
10 #include "src/string-search.h" | 10 #include "src/string-search.h" |
11 | 11 |
12 namespace v8 { | 12 namespace v8 { |
13 namespace internal { | 13 namespace internal { |
14 | 14 |
15 | |
16 // Perform string match of pattern on subject, starting at start index. | |
17 // Caller must ensure that 0 <= start_index <= sub->length(), | |
18 // and should check that pat->length() + start_index <= sub->length(). | |
19 int StringMatch(Isolate* isolate, Handle<String> sub, Handle<String> pat, | |
20 int start_index) { | |
21 DCHECK(0 <= start_index); | |
22 DCHECK(start_index <= sub->length()); | |
23 | |
24 int pattern_length = pat->length(); | |
25 if (pattern_length == 0) return start_index; | |
26 | |
27 int subject_length = sub->length(); | |
28 if (start_index + pattern_length > subject_length) return -1; | |
29 | |
30 sub = String::Flatten(sub); | |
31 pat = String::Flatten(pat); | |
32 | |
33 DisallowHeapAllocation no_gc; // ensure vectors stay valid | |
34 // Extract flattened substrings of cons strings before getting encoding. | |
35 String::FlatContent seq_sub = sub->GetFlatContent(); | |
36 String::FlatContent seq_pat = pat->GetFlatContent(); | |
37 | |
38 // dispatch on type of strings | |
39 if (seq_pat.IsOneByte()) { | |
40 Vector<const uint8_t> pat_vector = seq_pat.ToOneByteVector(); | |
41 if (seq_sub.IsOneByte()) { | |
42 return SearchString(isolate, seq_sub.ToOneByteVector(), pat_vector, | |
43 start_index); | |
44 } | |
45 return SearchString(isolate, seq_sub.ToUC16Vector(), pat_vector, | |
46 start_index); | |
47 } | |
48 Vector<const uc16> pat_vector = seq_pat.ToUC16Vector(); | |
49 if (seq_sub.IsOneByte()) { | |
50 return SearchString(isolate, seq_sub.ToOneByteVector(), pat_vector, | |
51 start_index); | |
52 } | |
53 return SearchString(isolate, seq_sub.ToUC16Vector(), pat_vector, start_index); | |
54 } | |
55 | |
56 | |
57 // This may return an empty MaybeHandle if an exception is thrown or | 15 // This may return an empty MaybeHandle if an exception is thrown or |
58 // we abort due to reaching the recursion limit. | 16 // we abort due to reaching the recursion limit. |
59 MaybeHandle<String> StringReplaceOneCharWithString( | 17 MaybeHandle<String> StringReplaceOneCharWithString( |
60 Isolate* isolate, Handle<String> subject, Handle<String> search, | 18 Isolate* isolate, Handle<String> subject, Handle<String> search, |
61 Handle<String> replace, bool* found, int recursion_limit) { | 19 Handle<String> replace, bool* found, int recursion_limit) { |
62 StackLimitCheck stackLimitCheck(isolate); | 20 StackLimitCheck stackLimitCheck(isolate); |
63 if (stackLimitCheck.HasOverflowed() || (recursion_limit == 0)) { | 21 if (stackLimitCheck.HasOverflowed() || (recursion_limit == 0)) { |
64 return MaybeHandle<String>(); | 22 return MaybeHandle<String>(); |
65 } | 23 } |
66 recursion_limit--; | 24 recursion_limit--; |
(...skipping 11 matching lines...) Expand all Loading... |
78 Handle<String> new_second; | 36 Handle<String> new_second; |
79 if (!StringReplaceOneCharWithString(isolate, second, search, replace, found, | 37 if (!StringReplaceOneCharWithString(isolate, second, search, replace, found, |
80 recursion_limit) | 38 recursion_limit) |
81 .ToHandle(&new_second)) { | 39 .ToHandle(&new_second)) { |
82 return MaybeHandle<String>(); | 40 return MaybeHandle<String>(); |
83 } | 41 } |
84 if (*found) return isolate->factory()->NewConsString(first, new_second); | 42 if (*found) return isolate->factory()->NewConsString(first, new_second); |
85 | 43 |
86 return subject; | 44 return subject; |
87 } else { | 45 } else { |
88 int index = StringMatch(isolate, subject, search, 0); | 46 int index = String::IndexOf(isolate, subject, search, 0); |
89 if (index == -1) return subject; | 47 if (index == -1) return subject; |
90 *found = true; | 48 *found = true; |
91 Handle<String> first = isolate->factory()->NewSubString(subject, 0, index); | 49 Handle<String> first = isolate->factory()->NewSubString(subject, 0, index); |
92 Handle<String> cons1; | 50 Handle<String> cons1; |
93 ASSIGN_RETURN_ON_EXCEPTION( | 51 ASSIGN_RETURN_ON_EXCEPTION( |
94 isolate, cons1, isolate->factory()->NewConsString(first, replace), | 52 isolate, cons1, isolate->factory()->NewConsString(first, replace), |
95 String); | 53 String); |
96 Handle<String> second = | 54 Handle<String> second = |
97 isolate->factory()->NewSubString(subject, index + 1, subject->length()); | 55 isolate->factory()->NewSubString(subject, index + 1, subject->length()); |
98 return isolate->factory()->NewConsString(cons1, second); | 56 return isolate->factory()->NewConsString(cons1, second); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 DCHECK(args.length() == 3); | 92 DCHECK(args.length() == 3); |
135 | 93 |
136 CONVERT_ARG_HANDLE_CHECKED(String, sub, 0); | 94 CONVERT_ARG_HANDLE_CHECKED(String, sub, 0); |
137 CONVERT_ARG_HANDLE_CHECKED(String, pat, 1); | 95 CONVERT_ARG_HANDLE_CHECKED(String, pat, 1); |
138 CONVERT_ARG_HANDLE_CHECKED(Object, index, 2); | 96 CONVERT_ARG_HANDLE_CHECKED(Object, index, 2); |
139 | 97 |
140 uint32_t start_index = 0; | 98 uint32_t start_index = 0; |
141 if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1); | 99 if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1); |
142 | 100 |
143 CHECK(start_index <= static_cast<uint32_t>(sub->length())); | 101 CHECK(start_index <= static_cast<uint32_t>(sub->length())); |
144 int position = StringMatch(isolate, sub, pat, start_index); | 102 int position = String::IndexOf(isolate, sub, pat, start_index); |
145 return Smi::FromInt(position); | 103 return Smi::FromInt(position); |
146 } | 104 } |
147 | 105 |
148 | 106 |
149 template <typename schar, typename pchar> | 107 template <typename schar, typename pchar> |
150 static int StringMatchBackwards(Vector<const schar> subject, | 108 static int StringMatchBackwards(Vector<const schar> subject, |
151 Vector<const pchar> pattern, int idx) { | 109 Vector<const pchar> pattern, int idx) { |
152 int pattern_length = pattern.length(); | 110 int pattern_length = pattern.length(); |
153 DCHECK(pattern_length >= 1); | 111 DCHECK(pattern_length >= 1); |
154 DCHECK(idx + pattern_length <= subject.length()); | 112 DCHECK(idx + pattern_length <= subject.length()); |
(...skipping 1055 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1210 SealHandleScope shs(isolate); | 1168 SealHandleScope shs(isolate); |
1211 DCHECK(args.length() == 2); | 1169 DCHECK(args.length() == 2); |
1212 if (!args[0]->IsString()) return isolate->heap()->undefined_value(); | 1170 if (!args[0]->IsString()) return isolate->heap()->undefined_value(); |
1213 if (!args[1]->IsNumber()) return isolate->heap()->undefined_value(); | 1171 if (!args[1]->IsNumber()) return isolate->heap()->undefined_value(); |
1214 if (std::isinf(args.number_at(1))) return isolate->heap()->nan_value(); | 1172 if (std::isinf(args.number_at(1))) return isolate->heap()->nan_value(); |
1215 return __RT_impl_Runtime_StringCharCodeAtRT(args, isolate); | 1173 return __RT_impl_Runtime_StringCharCodeAtRT(args, isolate); |
1216 } | 1174 } |
1217 | 1175 |
1218 } // namespace internal | 1176 } // namespace internal |
1219 } // namespace v8 | 1177 } // namespace v8 |
OLD | NEW |