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 1372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1383 Handle<Object> splitter_obj; | 1383 Handle<Object> splitter_obj; |
1384 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1384 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1385 isolate, splitter_obj, Execution::New(ctor_fun, argc, argv.start())); | 1385 isolate, splitter_obj, Execution::New(ctor_fun, argc, argv.start())); |
1386 | 1386 |
1387 splitter = Handle<JSReceiver>::cast(splitter_obj); | 1387 splitter = Handle<JSReceiver>::cast(splitter_obj); |
1388 } | 1388 } |
1389 | 1389 |
1390 uint32_t limit; | 1390 uint32_t limit; |
1391 RETURN_FAILURE_ON_EXCEPTION(isolate, ToUint32(isolate, limit_obj, &limit)); | 1391 RETURN_FAILURE_ON_EXCEPTION(isolate, ToUint32(isolate, limit_obj, &limit)); |
1392 | 1392 |
1393 const int length = string->length(); | 1393 const uint32_t length = string->length(); |
1394 | 1394 |
1395 if (limit == 0) return *factory->NewJSArray(0); | 1395 if (limit == 0) return *factory->NewJSArray(0); |
1396 | 1396 |
1397 if (length == 0) { | 1397 if (length == 0) { |
1398 Handle<Object> result; | 1398 Handle<Object> result; |
1399 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1399 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1400 isolate, result, RegExpUtils::RegExpExec(isolate, splitter, string, | 1400 isolate, result, RegExpUtils::RegExpExec(isolate, splitter, string, |
1401 factory->undefined_value())); | 1401 factory->undefined_value())); |
1402 | 1402 |
1403 if (!result->IsNull(isolate)) return *factory->NewJSArray(0); | 1403 if (!result->IsNull(isolate)) return *factory->NewJSArray(0); |
1404 | 1404 |
1405 Handle<FixedArray> elems = factory->NewUninitializedFixedArray(1); | 1405 Handle<FixedArray> elems = factory->NewUninitializedFixedArray(1); |
1406 elems->set(0, *string); | 1406 elems->set(0, *string); |
1407 return *factory->NewJSArrayWithElements(elems); | 1407 return *factory->NewJSArrayWithElements(elems); |
1408 } | 1408 } |
1409 | 1409 |
1410 static const int kInitialArraySize = 8; | 1410 static const int kInitialArraySize = 8; |
1411 Handle<FixedArray> elems = factory->NewFixedArrayWithHoles(kInitialArraySize); | 1411 Handle<FixedArray> elems = factory->NewFixedArrayWithHoles(kInitialArraySize); |
1412 int num_elems = 0; | 1412 int num_elems = 0; |
1413 | 1413 |
1414 int string_index = 0; | 1414 uint32_t string_index = 0; |
1415 int prev_string_index = 0; | 1415 uint32_t prev_string_index = 0; |
1416 while (string_index < length) { | 1416 while (string_index < length) { |
1417 RETURN_FAILURE_ON_EXCEPTION( | 1417 RETURN_FAILURE_ON_EXCEPTION( |
1418 isolate, RegExpUtils::SetLastIndex(isolate, splitter, string_index)); | 1418 isolate, RegExpUtils::SetLastIndex(isolate, splitter, string_index)); |
1419 | 1419 |
1420 Handle<Object> result; | 1420 Handle<Object> result; |
1421 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1421 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1422 isolate, result, RegExpUtils::RegExpExec(isolate, splitter, string, | 1422 isolate, result, RegExpUtils::RegExpExec(isolate, splitter, string, |
1423 factory->undefined_value())); | 1423 factory->undefined_value())); |
1424 | 1424 |
1425 if (result->IsNull(isolate)) { | 1425 if (result->IsNull(isolate)) { |
1426 string_index = RegExpUtils::AdvanceStringIndex(isolate, string, | 1426 string_index = RegExpUtils::AdvanceStringIndex(isolate, string, |
1427 string_index, unicode); | 1427 string_index, unicode); |
1428 continue; | 1428 continue; |
1429 } | 1429 } |
1430 | 1430 |
1431 Handle<Object> last_index_obj; | 1431 Handle<Object> last_index_obj; |
1432 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1432 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1433 isolate, last_index_obj, RegExpUtils::GetLastIndex(isolate, splitter)); | 1433 isolate, last_index_obj, RegExpUtils::GetLastIndex(isolate, splitter)); |
1434 | 1434 |
1435 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1435 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1436 isolate, last_index_obj, Object::ToLength(isolate, last_index_obj)); | 1436 isolate, last_index_obj, Object::ToLength(isolate, last_index_obj)); |
1437 const int last_index = Handle<Smi>::cast(last_index_obj)->value(); | |
1438 | 1437 |
1439 const int end = std::min(last_index, length); | 1438 const uint32_t end = |
| 1439 std::min(PositiveNumberToUint32(*last_index_obj), length); |
1440 if (end == prev_string_index) { | 1440 if (end == prev_string_index) { |
1441 string_index = RegExpUtils::AdvanceStringIndex(isolate, string, | 1441 string_index = RegExpUtils::AdvanceStringIndex(isolate, string, |
1442 string_index, unicode); | 1442 string_index, unicode); |
1443 continue; | 1443 continue; |
1444 } | 1444 } |
1445 | 1445 |
1446 { | 1446 { |
1447 Handle<String> substr = | 1447 Handle<String> substr = |
1448 factory->NewSubString(string, prev_string_index, string_index); | 1448 factory->NewSubString(string, prev_string_index, string_index); |
1449 elems = FixedArray::SetAndGrow(elems, num_elems++, substr); | 1449 elems = FixedArray::SetAndGrow(elems, num_elems++, substr); |
1450 if (static_cast<uint32_t>(num_elems) == limit) { | 1450 if (static_cast<uint32_t>(num_elems) == limit) { |
1451 return *NewJSArrayWithElements(isolate, elems, num_elems); | 1451 return *NewJSArrayWithElements(isolate, elems, num_elems); |
1452 } | 1452 } |
1453 } | 1453 } |
1454 | 1454 |
1455 prev_string_index = end; | 1455 prev_string_index = end; |
1456 | 1456 |
1457 Handle<Object> num_captures_obj; | 1457 Handle<Object> num_captures_obj; |
1458 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1458 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1459 isolate, num_captures_obj, | 1459 isolate, num_captures_obj, |
1460 Object::GetProperty(result, isolate->factory()->length_string())); | 1460 Object::GetProperty(result, isolate->factory()->length_string())); |
1461 | 1461 |
1462 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1462 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1463 isolate, num_captures_obj, Object::ToLength(isolate, num_captures_obj)); | 1463 isolate, num_captures_obj, Object::ToLength(isolate, num_captures_obj)); |
1464 const int num_captures = | 1464 const int num_captures = PositiveNumberToUint32(*num_captures_obj); |
1465 std::max(Handle<Smi>::cast(num_captures_obj)->value(), 0); | |
1466 | 1465 |
1467 for (int i = 1; i < num_captures; i++) { | 1466 for (int i = 1; i < num_captures; i++) { |
1468 Handle<Object> capture; | 1467 Handle<Object> capture; |
1469 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1468 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1470 isolate, capture, Object::GetElement(isolate, result, i)); | 1469 isolate, capture, Object::GetElement(isolate, result, i)); |
1471 elems = FixedArray::SetAndGrow(elems, num_elems++, capture); | 1470 elems = FixedArray::SetAndGrow(elems, num_elems++, capture); |
1472 if (static_cast<uint32_t>(num_elems) == limit) { | 1471 if (static_cast<uint32_t>(num_elems) == limit) { |
1473 return *NewJSArrayWithElements(isolate, elems, num_elems); | 1472 return *NewJSArrayWithElements(isolate, elems, num_elems); |
1474 } | 1473 } |
1475 } | 1474 } |
(...skipping 25 matching lines...) Expand all Loading... |
1501 | 1500 |
1502 string = String::Flatten(string); | 1501 string = String::Flatten(string); |
1503 | 1502 |
1504 // Fast-path for unmodified JSRegExps. | 1503 // Fast-path for unmodified JSRegExps. |
1505 if (RegExpUtils::IsUnmodifiedRegExp(isolate, recv)) { | 1504 if (RegExpUtils::IsUnmodifiedRegExp(isolate, recv)) { |
1506 RETURN_RESULT_OR_FAILURE( | 1505 RETURN_RESULT_OR_FAILURE( |
1507 isolate, RegExpReplace(isolate, Handle<JSRegExp>::cast(recv), string, | 1506 isolate, RegExpReplace(isolate, Handle<JSRegExp>::cast(recv), string, |
1508 replace_obj)); | 1507 replace_obj)); |
1509 } | 1508 } |
1510 | 1509 |
1511 const int length = string->length(); | 1510 const uint32_t length = string->length(); |
1512 const bool functional_replace = replace_obj->IsCallable(); | 1511 const bool functional_replace = replace_obj->IsCallable(); |
1513 | 1512 |
1514 Handle<String> replace; | 1513 Handle<String> replace; |
1515 if (!functional_replace) { | 1514 if (!functional_replace) { |
1516 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, replace, | 1515 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, replace, |
1517 Object::ToString(isolate, replace_obj)); | 1516 Object::ToString(isolate, replace_obj)); |
1518 } | 1517 } |
1519 | 1518 |
1520 Handle<Object> global_obj; | 1519 Handle<Object> global_obj; |
1521 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1520 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1558 Object::ToString(isolate, match_obj)); | 1557 Object::ToString(isolate, match_obj)); |
1559 | 1558 |
1560 if (match->length() == 0) { | 1559 if (match->length() == 0) { |
1561 RETURN_FAILURE_ON_EXCEPTION(isolate, RegExpUtils::SetAdvancedStringIndex( | 1560 RETURN_FAILURE_ON_EXCEPTION(isolate, RegExpUtils::SetAdvancedStringIndex( |
1562 isolate, recv, string, unicode)); | 1561 isolate, recv, string, unicode)); |
1563 } | 1562 } |
1564 } | 1563 } |
1565 | 1564 |
1566 // TODO(jgruber): Look into ReplacementStringBuilder instead. | 1565 // TODO(jgruber): Look into ReplacementStringBuilder instead. |
1567 IncrementalStringBuilder builder(isolate); | 1566 IncrementalStringBuilder builder(isolate); |
1568 int next_source_position = 0; | 1567 uint32_t next_source_position = 0; |
1569 | 1568 |
1570 for (const auto& result : results) { | 1569 for (const auto& result : results) { |
1571 Handle<Object> captures_length_obj; | 1570 Handle<Object> captures_length_obj; |
1572 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1571 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1573 isolate, captures_length_obj, | 1572 isolate, captures_length_obj, |
1574 Object::GetProperty(result, factory->length_string())); | 1573 Object::GetProperty(result, factory->length_string())); |
1575 | 1574 |
1576 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1575 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1577 isolate, captures_length_obj, | 1576 isolate, captures_length_obj, |
1578 Object::ToLength(isolate, captures_length_obj)); | 1577 Object::ToLength(isolate, captures_length_obj)); |
1579 const int captures_length = | 1578 const int captures_length = PositiveNumberToUint32(*captures_length_obj); |
1580 std::max(Handle<Smi>::cast(captures_length_obj)->value(), 0); | |
1581 | 1579 |
1582 Handle<Object> match_obj; | 1580 Handle<Object> match_obj; |
1583 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, match_obj, | 1581 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, match_obj, |
1584 Object::GetElement(isolate, result, 0)); | 1582 Object::GetElement(isolate, result, 0)); |
1585 | 1583 |
1586 Handle<String> match; | 1584 Handle<String> match; |
1587 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, match, | 1585 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, match, |
1588 Object::ToString(isolate, match_obj)); | 1586 Object::ToString(isolate, match_obj)); |
1589 | 1587 |
1590 const int match_length = match->length(); | 1588 const int match_length = match->length(); |
1591 | 1589 |
1592 Handle<Object> position_obj; | 1590 Handle<Object> position_obj; |
1593 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1591 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1594 isolate, position_obj, | 1592 isolate, position_obj, |
1595 Object::GetProperty(result, factory->index_string())); | 1593 Object::GetProperty(result, factory->index_string())); |
1596 | 1594 |
1597 // TODO(jgruber): Extract and correct error handling. Since we can go up to | 1595 // TODO(jgruber): Extract and correct error handling. Since we can go up to |
1598 // 2^53 - 1 (at least for ToLength), we might actually need uint64_t here? | 1596 // 2^53 - 1 (at least for ToLength), we might actually need uint64_t here? |
1599 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1597 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1600 isolate, position_obj, Object::ToInteger(isolate, position_obj)); | 1598 isolate, position_obj, Object::ToInteger(isolate, position_obj)); |
1601 const int position = | 1599 const uint32_t position = |
1602 std::max(std::min(Handle<Smi>::cast(position_obj)->value(), length), 0); | 1600 std::min(PositiveNumberToUint32(*position_obj), length); |
1603 | 1601 |
1604 ZoneVector<Handle<Object>> captures(&zone); | 1602 ZoneVector<Handle<Object>> captures(&zone); |
1605 for (int n = 0; n < captures_length; n++) { | 1603 for (int n = 0; n < captures_length; n++) { |
1606 Handle<Object> capture; | 1604 Handle<Object> capture; |
1607 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1605 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1608 isolate, capture, Object::GetElement(isolate, result, n)); | 1606 isolate, capture, Object::GetElement(isolate, result, n)); |
1609 | 1607 |
1610 if (!capture->IsUndefined(isolate)) { | 1608 if (!capture->IsUndefined(isolate)) { |
1611 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, capture, | 1609 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, capture, |
1612 Object::ToString(isolate, capture)); | 1610 Object::ToString(isolate, capture)); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1680 | 1678 |
1681 RUNTIME_FUNCTION(Runtime_IsRegExp) { | 1679 RUNTIME_FUNCTION(Runtime_IsRegExp) { |
1682 SealHandleScope shs(isolate); | 1680 SealHandleScope shs(isolate); |
1683 DCHECK(args.length() == 1); | 1681 DCHECK(args.length() == 1); |
1684 CONVERT_ARG_CHECKED(Object, obj, 0); | 1682 CONVERT_ARG_CHECKED(Object, obj, 0); |
1685 return isolate->heap()->ToBoolean(obj->IsJSRegExp()); | 1683 return isolate->heap()->ToBoolean(obj->IsJSRegExp()); |
1686 } | 1684 } |
1687 | 1685 |
1688 } // namespace internal | 1686 } // namespace internal |
1689 } // namespace v8 | 1687 } // namespace v8 |
OLD | NEW |