| OLD | NEW |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/builtins/builtins-regexp.h" | 5 #include "src/builtins/builtins-regexp.h" |
| 6 #include "src/builtins/builtins-utils.h" | 6 #include "src/builtins/builtins-utils.h" |
| 7 #include "src/builtins/builtins.h" | 7 #include "src/builtins/builtins.h" |
| 8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
| 9 #include "src/code-stub-assembler.h" | 9 #include "src/code-stub-assembler.h" |
| 10 #include "src/regexp/regexp-utils.h" | 10 #include "src/regexp/regexp-utils.h" |
| (...skipping 1162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1173 replace); | 1173 replace); |
| 1174 }, | 1174 }, |
| 1175 [=](Node* fn) { | 1175 [=](Node* fn) { |
| 1176 Callable call_callable = CodeFactory::Call(isolate()); | 1176 Callable call_callable = CodeFactory::Call(isolate()); |
| 1177 return CallJS(call_callable, context, fn, search, receiver, replace); | 1177 return CallJS(call_callable, context, fn, search, receiver, replace); |
| 1178 }); | 1178 }); |
| 1179 | 1179 |
| 1180 // Convert {receiver} and {search} to strings. | 1180 // Convert {receiver} and {search} to strings. |
| 1181 | 1181 |
| 1182 Callable tostring_callable = CodeFactory::ToString(isolate()); | 1182 Callable tostring_callable = CodeFactory::ToString(isolate()); |
| 1183 Callable indexof_callable = CodeFactory::StringIndexOf(isolate()); |
| 1184 |
| 1183 Node* const subject_string = CallStub(tostring_callable, context, receiver); | 1185 Node* const subject_string = CallStub(tostring_callable, context, receiver); |
| 1184 Node* const search_string = CallStub(tostring_callable, context, search); | 1186 Node* const search_string = CallStub(tostring_callable, context, search); |
| 1185 | 1187 |
| 1186 Node* const subject_length = LoadStringLength(subject_string); | 1188 Node* const subject_length = LoadStringLength(subject_string); |
| 1187 Node* const search_length = LoadStringLength(search_string); | 1189 Node* const search_length = LoadStringLength(search_string); |
| 1188 | 1190 |
| 1189 // Fast-path single-char {search}, long {receiver}, and simple string | 1191 // Fast-path single-char {search}, long {receiver}, and simple string |
| 1190 // {replace}. | 1192 // {replace}. |
| 1191 { | 1193 { |
| 1192 Label next(this); | 1194 Label next(this); |
| 1193 | 1195 |
| 1194 GotoUnless(SmiEqual(search_length, SmiConstant(1)), &next); | 1196 GotoUnless(SmiEqual(search_length, SmiConstant(1)), &next); |
| 1195 GotoUnless(SmiGreaterThan(subject_length, SmiConstant(0xFF)), &next); | 1197 GotoUnless(SmiGreaterThan(subject_length, SmiConstant(0xFF)), &next); |
| 1196 GotoIf(TaggedIsSmi(replace), &next); | 1198 GotoIf(TaggedIsSmi(replace), &next); |
| 1197 GotoUnless(IsString(replace), &next); | 1199 GotoUnless(IsString(replace), &next); |
| 1198 | 1200 |
| 1199 Node* const dollar_char = Int32Constant('$'); | 1201 Node* const dollar_string = HeapConstant( |
| 1200 Node* const index_of_dollar = | 1202 isolate()->factory()->LookupSingleCharacterStringFromCode('$')); |
| 1201 StringIndexOfChar(context, replace, dollar_char, smi_zero); | 1203 Node* const dollar_ix = |
| 1202 GotoUnless(SmiIsNegative(index_of_dollar), &next); | 1204 CallStub(indexof_callable, context, replace, dollar_string, smi_zero); |
| 1205 GotoUnless(SmiIsNegative(dollar_ix), &next); |
| 1203 | 1206 |
| 1204 // Searching by traversing a cons string tree and replace with cons of | 1207 // Searching by traversing a cons string tree and replace with cons of |
| 1205 // slices works only when the replaced string is a single character, being | 1208 // slices works only when the replaced string is a single character, being |
| 1206 // replaced by a simple string and only pays off for long strings. | 1209 // replaced by a simple string and only pays off for long strings. |
| 1207 // TODO(jgruber): Reevaluate if this is still beneficial. | 1210 // TODO(jgruber): Reevaluate if this is still beneficial. |
| 1208 TailCallRuntime(Runtime::kStringReplaceOneCharWithString, context, | 1211 TailCallRuntime(Runtime::kStringReplaceOneCharWithString, context, |
| 1209 subject_string, search_string, replace); | 1212 subject_string, search_string, replace); |
| 1210 | 1213 |
| 1211 Bind(&next); | 1214 Bind(&next); |
| 1212 } | 1215 } |
| 1213 | 1216 |
| 1214 // TODO(jgruber): Extend StringIndexOfChar to handle two-byte strings and | 1217 // TODO(jgruber): Extend StringIndexOf to handle two-byte strings and |
| 1215 // longer substrings - we can handle up to 8 chars (one-byte) / 4 chars | 1218 // longer substrings - we can handle up to 8 chars (one-byte) / 4 chars |
| 1216 // (2-byte). | 1219 // (2-byte). |
| 1217 | 1220 |
| 1218 Callable indexof_stub = CodeFactory::StringIndexOf(isolate()); | 1221 Node* const match_start_index = CallStub( |
| 1219 Node* const match_start_index = | 1222 indexof_callable, context, subject_string, search_string, smi_zero); |
| 1220 CallStub(indexof_stub, context, subject_string, search_string, smi_zero); | |
| 1221 CSA_ASSERT(this, TaggedIsSmi(match_start_index)); | 1223 CSA_ASSERT(this, TaggedIsSmi(match_start_index)); |
| 1222 | 1224 |
| 1223 // Early exit if no match found. | 1225 // Early exit if no match found. |
| 1224 { | 1226 { |
| 1225 Label next(this), return_subject(this); | 1227 Label next(this), return_subject(this); |
| 1226 | 1228 |
| 1227 GotoUnless(SmiIsNegative(match_start_index), &next); | 1229 GotoUnless(SmiIsNegative(match_start_index), &next); |
| 1228 | 1230 |
| 1229 // The spec requires to perform ToString(replace) if the {replace} is not | 1231 // The spec requires to perform ToString(replace) if the {replace} is not |
| 1230 // callable even if we are going to exit here. | 1232 // callable even if we are going to exit here. |
| (...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1871 CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context, | 1873 CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context, |
| 1872 HeapConstant(factory()->NewStringFromAsciiChecked( | 1874 HeapConstant(factory()->NewStringFromAsciiChecked( |
| 1873 "String Iterator.prototype.next", TENURED)), | 1875 "String Iterator.prototype.next", TENURED)), |
| 1874 iterator); | 1876 iterator); |
| 1875 Return(result); // Never reached. | 1877 Return(result); // Never reached. |
| 1876 } | 1878 } |
| 1877 } | 1879 } |
| 1878 | 1880 |
| 1879 } // namespace internal | 1881 } // namespace internal |
| 1880 } // namespace v8 | 1882 } // namespace v8 |
| OLD | NEW |