Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(165)

Side by Side Diff: src/runtime/runtime-regexp.cc

Issue 2532403002: [regexp] Migrate @@split to TurboFan (Closed)
Patch Set: Address comments Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 1251 matching lines...) Expand 10 before | Expand all | Expand 10 after
1262 DCHECK(args.length() == 3); 1262 DCHECK(args.length() == 3);
1263 1263
1264 CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); 1264 CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
1265 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1); 1265 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
1266 CONVERT_ARG_HANDLE_CHECKED(JSObject, replace, 2); 1266 CONVERT_ARG_HANDLE_CHECKED(JSObject, replace, 2);
1267 1267
1268 RETURN_RESULT_OR_FAILURE(isolate, StringReplaceNonGlobalRegExpWithFunction( 1268 RETURN_RESULT_OR_FAILURE(isolate, StringReplaceNonGlobalRegExpWithFunction(
1269 isolate, subject, regexp, replace)); 1269 isolate, subject, regexp, replace));
1270 } 1270 }
1271 1271
1272 namespace {
1273
1274 // ES##sec-speciesconstructor
1275 // SpeciesConstructor ( O, defaultConstructor )
1276 MUST_USE_RESULT MaybeHandle<Object> SpeciesConstructor(
1277 Isolate* isolate, Handle<JSReceiver> recv,
1278 Handle<JSFunction> default_ctor) {
1279 Handle<Object> ctor_obj;
1280 ASSIGN_RETURN_ON_EXCEPTION(
1281 isolate, ctor_obj,
1282 JSObject::GetProperty(recv, isolate->factory()->constructor_string()),
1283 Object);
1284
1285 if (ctor_obj->IsUndefined(isolate)) return default_ctor;
1286
1287 if (!ctor_obj->IsJSReceiver()) {
1288 THROW_NEW_ERROR(isolate,
1289 NewTypeError(MessageTemplate::kConstructorNotReceiver),
1290 Object);
1291 }
1292
1293 Handle<JSReceiver> ctor = Handle<JSReceiver>::cast(ctor_obj);
1294
1295 Handle<Object> species;
1296 ASSIGN_RETURN_ON_EXCEPTION(
1297 isolate, species,
1298 JSObject::GetProperty(ctor, isolate->factory()->species_symbol()),
1299 Object);
1300
1301 if (species->IsNull(isolate) || species->IsUndefined(isolate)) {
1302 return default_ctor;
1303 }
1304
1305 if (species->IsConstructor()) return species;
1306
1307 THROW_NEW_ERROR(
1308 isolate, NewTypeError(MessageTemplate::kSpeciesNotConstructor), Object);
1309 }
1310
1311 MUST_USE_RESULT MaybeHandle<Object> ToUint32(Isolate* isolate,
1312 Handle<Object> object,
1313 uint32_t* out) {
1314 if (object->IsUndefined(isolate)) {
1315 *out = kMaxUInt32;
1316 return object;
1317 }
1318
1319 Handle<Object> number;
1320 ASSIGN_RETURN_ON_EXCEPTION(isolate, number, Object::ToNumber(object), Object);
1321 *out = NumberToUint32(*number);
1322 return object;
1323 }
1324
1325 Handle<JSArray> NewJSArrayWithElements(Isolate* isolate,
1326 Handle<FixedArray> elems,
1327 int num_elems) {
1328 elems->Shrink(num_elems);
1329 return isolate->factory()->NewJSArrayWithElements(elems);
1330 }
1331
1332 } // namespace
1333
1334 // Slow path for:
1335 // ES#sec-regexp.prototype-@@replace
1336 // RegExp.prototype [ @@split ] ( string, limit )
1337 RUNTIME_FUNCTION(Runtime_RegExpSplit) {
1338 HandleScope scope(isolate);
1339 DCHECK(args.length() == 3);
1340
1341 DCHECK(args[1]->IsString());
1342
1343 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, recv, 0);
1344 CONVERT_ARG_HANDLE_CHECKED(String, string, 1);
1345 CONVERT_ARG_HANDLE_CHECKED(Object, limit_obj, 2);
1346
1347 Factory* factory = isolate->factory();
1348
1349 Handle<JSFunction> regexp_fun = isolate->regexp_function();
1350 Handle<Object> ctor;
1351 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1352 isolate, ctor, SpeciesConstructor(isolate, recv, regexp_fun));
1353
1354 Handle<Object> flags_obj;
1355 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1356 isolate, flags_obj, JSObject::GetProperty(recv, factory->flags_string()));
1357
1358 Handle<String> flags;
1359 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, flags,
1360 Object::ToString(isolate, flags_obj));
1361
1362 Handle<String> u_str = factory->LookupSingleCharacterStringFromCode('u');
1363 const bool unicode = (String::IndexOf(isolate, flags, u_str, 0) >= 0);
1364
1365 Handle<String> y_str = factory->LookupSingleCharacterStringFromCode('y');
1366 const bool sticky = (String::IndexOf(isolate, flags, y_str, 0) >= 0);
1367
1368 Handle<String> new_flags = flags;
1369 if (!sticky) {
1370 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, new_flags,
1371 factory->NewConsString(flags, y_str));
1372 }
1373
1374 Handle<JSReceiver> splitter;
1375 {
1376 const int argc = 2;
1377
1378 ScopedVector<Handle<Object>> argv(argc);
1379 argv[0] = recv;
1380 argv[1] = new_flags;
1381
1382 Handle<JSFunction> ctor_fun = Handle<JSFunction>::cast(ctor);
1383 Handle<Object> splitter_obj;
1384 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1385 isolate, splitter_obj, Execution::New(ctor_fun, argc, argv.start()));
1386
1387 splitter = Handle<JSReceiver>::cast(splitter_obj);
1388 }
1389
1390 uint32_t limit;
1391 RETURN_FAILURE_ON_EXCEPTION(isolate, ToUint32(isolate, limit_obj, &limit));
1392
1393 const int length = string->length();
1394
1395 if (limit == 0) return *factory->NewJSArray(0);
1396
1397 if (length == 0) {
1398 Handle<Object> result;
1399 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1400 isolate, result, RegExpUtils::RegExpExec(isolate, splitter, string,
1401 factory->undefined_value()));
1402
1403 if (!result->IsNull(isolate)) return *factory->NewJSArray(0);
1404
1405 Handle<FixedArray> elems = factory->NewUninitializedFixedArray(1);
1406 elems->set(0, *string);
1407 return *factory->NewJSArrayWithElements(elems);
1408 }
1409
1410 static const int kInitialArraySize = 8;
1411 Handle<FixedArray> elems = factory->NewFixedArrayWithHoles(kInitialArraySize);
1412 int num_elems = 0;
1413
1414 int string_index = 0;
1415 int prev_string_index = 0;
1416 while (string_index < length) {
1417 RETURN_FAILURE_ON_EXCEPTION(
1418 isolate, RegExpUtils::SetLastIndex(isolate, splitter, string_index));
1419
1420 Handle<Object> result;
1421 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1422 isolate, result, RegExpUtils::RegExpExec(isolate, splitter, string,
1423 factory->undefined_value()));
1424
1425 if (result->IsNull(isolate)) {
1426 string_index = RegExpUtils::AdvanceStringIndex(isolate, string,
1427 string_index, unicode);
1428 continue;
1429 }
1430
1431 Handle<Object> last_index_obj;
1432 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1433 isolate, last_index_obj, RegExpUtils::GetLastIndex(isolate, splitter));
1434
1435 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1436 isolate, last_index_obj, Object::ToLength(isolate, last_index_obj));
1437 const int last_index = Handle<Smi>::cast(last_index_obj)->value();
1438
1439 const int end = std::min(last_index, length);
1440 if (end == prev_string_index) {
1441 string_index = RegExpUtils::AdvanceStringIndex(isolate, string,
1442 string_index, unicode);
1443 continue;
1444 }
1445
1446 {
1447 Handle<String> substr =
1448 factory->NewSubString(string, prev_string_index, string_index);
1449 elems = FixedArray::SetAndGrow(elems, num_elems++, substr);
1450 if (static_cast<uint32_t>(num_elems) == limit) {
1451 return *NewJSArrayWithElements(isolate, elems, num_elems);
1452 }
1453 }
1454
1455 prev_string_index = end;
1456
1457 Handle<Object> num_captures_obj;
1458 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1459 isolate, num_captures_obj,
1460 Object::GetProperty(result, isolate->factory()->length_string()));
1461
1462 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1463 isolate, num_captures_obj, Object::ToLength(isolate, num_captures_obj));
1464 const int num_captures =
1465 std::max(Handle<Smi>::cast(num_captures_obj)->value(), 0);
1466
1467 for (int i = 1; i < num_captures; i++) {
1468 Handle<Object> capture;
1469 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1470 isolate, capture, Object::GetElement(isolate, result, i));
1471 elems = FixedArray::SetAndGrow(elems, num_elems++, capture);
1472 if (static_cast<uint32_t>(num_elems) == limit) {
1473 return *NewJSArrayWithElements(isolate, elems, num_elems);
1474 }
1475 }
1476
1477 string_index = prev_string_index;
1478 }
1479
1480 {
1481 Handle<String> substr =
1482 factory->NewSubString(string, prev_string_index, length);
1483 elems = FixedArray::SetAndGrow(elems, num_elems++, substr);
1484 }
1485
1486 return *NewJSArrayWithElements(isolate, elems, num_elems);
1487 }
1488
1272 // Slow path for: 1489 // Slow path for:
1273 // ES#sec-regexp.prototype-@@replace 1490 // ES#sec-regexp.prototype-@@replace
1274 // RegExp.prototype [ @@replace ] ( string, replaceValue ) 1491 // RegExp.prototype [ @@replace ] ( string, replaceValue )
1275 RUNTIME_FUNCTION(Runtime_RegExpReplace) { 1492 RUNTIME_FUNCTION(Runtime_RegExpReplace) {
1276 HandleScope scope(isolate); 1493 HandleScope scope(isolate);
1277 DCHECK(args.length() == 3); 1494 DCHECK(args.length() == 3);
1278 1495
1279 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, recv, 0); 1496 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, recv, 0);
1280 CONVERT_ARG_HANDLE_CHECKED(String, string, 1); 1497 CONVERT_ARG_HANDLE_CHECKED(String, string, 1);
1281 Handle<Object> replace_obj = args.at<Object>(2); 1498 Handle<Object> replace_obj = args.at<Object>(2);
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1451 1668
1452 RUNTIME_FUNCTION(Runtime_IsRegExp) { 1669 RUNTIME_FUNCTION(Runtime_IsRegExp) {
1453 SealHandleScope shs(isolate); 1670 SealHandleScope shs(isolate);
1454 DCHECK(args.length() == 1); 1671 DCHECK(args.length() == 1);
1455 CONVERT_ARG_CHECKED(Object, obj, 0); 1672 CONVERT_ARG_CHECKED(Object, obj, 0);
1456 return isolate->heap()->ToBoolean(obj->IsJSRegExp()); 1673 return isolate->heap()->ToBoolean(obj->IsJSRegExp());
1457 } 1674 }
1458 1675
1459 } // namespace internal 1676 } // namespace internal
1460 } // namespace v8 1677 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698