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/regexp/jsregexp-inl.h" | 10 #include "src/regexp/jsregexp-inl.h" |
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 490 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
491 isolate, answer, isolate->factory()->NewRawTwoByteString(length)); | 491 isolate, answer, isolate->factory()->NewRawTwoByteString(length)); |
492 StringBuilderConcatHelper(*special, answer->GetChars(), | 492 StringBuilderConcatHelper(*special, answer->GetChars(), |
493 FixedArray::cast(array->elements()), | 493 FixedArray::cast(array->elements()), |
494 array_length); | 494 array_length); |
495 return *answer; | 495 return *answer; |
496 } | 496 } |
497 } | 497 } |
498 | 498 |
499 | 499 |
| 500 RUNTIME_FUNCTION(Runtime_StringBuilderJoin) { |
| 501 HandleScope scope(isolate); |
| 502 DCHECK(args.length() == 3); |
| 503 CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0); |
| 504 int32_t array_length; |
| 505 if (!args[1]->ToInt32(&array_length)) { |
| 506 THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError()); |
| 507 } |
| 508 CONVERT_ARG_HANDLE_CHECKED(String, separator, 2); |
| 509 RUNTIME_ASSERT(array->HasFastObjectElements()); |
| 510 RUNTIME_ASSERT(array_length >= 0); |
| 511 |
| 512 Handle<FixedArray> fixed_array(FixedArray::cast(array->elements())); |
| 513 if (fixed_array->length() < array_length) { |
| 514 array_length = fixed_array->length(); |
| 515 } |
| 516 |
| 517 if (array_length == 0) { |
| 518 return isolate->heap()->empty_string(); |
| 519 } else if (array_length == 1) { |
| 520 Object* first = fixed_array->get(0); |
| 521 RUNTIME_ASSERT(first->IsString()); |
| 522 return first; |
| 523 } |
| 524 |
| 525 int separator_length = separator->length(); |
| 526 RUNTIME_ASSERT(separator_length > 0); |
| 527 int max_nof_separators = |
| 528 (String::kMaxLength + separator_length - 1) / separator_length; |
| 529 if (max_nof_separators < (array_length - 1)) { |
| 530 THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError()); |
| 531 } |
| 532 int length = (array_length - 1) * separator_length; |
| 533 for (int i = 0; i < array_length; i++) { |
| 534 Object* element_obj = fixed_array->get(i); |
| 535 RUNTIME_ASSERT(element_obj->IsString()); |
| 536 String* element = String::cast(element_obj); |
| 537 int increment = element->length(); |
| 538 if (increment > String::kMaxLength - length) { |
| 539 STATIC_ASSERT(String::kMaxLength < kMaxInt); |
| 540 length = kMaxInt; // Provoke exception; |
| 541 break; |
| 542 } |
| 543 length += increment; |
| 544 } |
| 545 |
| 546 Handle<SeqTwoByteString> answer; |
| 547 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 548 isolate, answer, isolate->factory()->NewRawTwoByteString(length)); |
| 549 |
| 550 DisallowHeapAllocation no_gc; |
| 551 |
| 552 uc16* sink = answer->GetChars(); |
| 553 #ifdef DEBUG |
| 554 uc16* end = sink + length; |
| 555 #endif |
| 556 |
| 557 RUNTIME_ASSERT(fixed_array->get(0)->IsString()); |
| 558 String* first = String::cast(fixed_array->get(0)); |
| 559 String* separator_raw = *separator; |
| 560 int first_length = first->length(); |
| 561 String::WriteToFlat(first, sink, 0, first_length); |
| 562 sink += first_length; |
| 563 |
| 564 for (int i = 1; i < array_length; i++) { |
| 565 DCHECK(sink + separator_length <= end); |
| 566 String::WriteToFlat(separator_raw, sink, 0, separator_length); |
| 567 sink += separator_length; |
| 568 |
| 569 RUNTIME_ASSERT(fixed_array->get(i)->IsString()); |
| 570 String* element = String::cast(fixed_array->get(i)); |
| 571 int element_length = element->length(); |
| 572 DCHECK(sink + element_length <= end); |
| 573 String::WriteToFlat(element, sink, 0, element_length); |
| 574 sink += element_length; |
| 575 } |
| 576 DCHECK(sink == end); |
| 577 |
| 578 // Use %_FastOneByteArrayJoin instead. |
| 579 DCHECK(!answer->IsOneByteRepresentation()); |
| 580 return *answer; |
| 581 } |
| 582 |
500 template <typename Char> | 583 template <typename Char> |
501 static void JoinSparseArrayWithSeparator(FixedArray* elements, | 584 static void JoinSparseArrayWithSeparator(FixedArray* elements, |
502 int elements_length, | 585 int elements_length, |
503 uint32_t array_length, | 586 uint32_t array_length, |
504 String* separator, | 587 String* separator, |
505 Vector<Char> buffer) { | 588 Vector<Char> buffer) { |
506 DisallowHeapAllocation no_gc; | 589 DisallowHeapAllocation no_gc; |
507 int previous_separator_position = 0; | 590 int previous_separator_position = 0; |
508 int separator_length = separator->length(); | 591 int separator_length = separator->length(); |
509 int cursor = 0; | 592 int cursor = 0; |
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1226 SealHandleScope shs(isolate); | 1309 SealHandleScope shs(isolate); |
1227 DCHECK(args.length() == 2); | 1310 DCHECK(args.length() == 2); |
1228 if (!args[0]->IsString()) return isolate->heap()->undefined_value(); | 1311 if (!args[0]->IsString()) return isolate->heap()->undefined_value(); |
1229 if (!args[1]->IsNumber()) return isolate->heap()->undefined_value(); | 1312 if (!args[1]->IsNumber()) return isolate->heap()->undefined_value(); |
1230 if (std::isinf(args.number_at(1))) return isolate->heap()->nan_value(); | 1313 if (std::isinf(args.number_at(1))) return isolate->heap()->nan_value(); |
1231 return __RT_impl_Runtime_StringCharCodeAtRT(args, isolate); | 1314 return __RT_impl_Runtime_StringCharCodeAtRT(args, isolate); |
1232 } | 1315 } |
1233 | 1316 |
1234 } // namespace internal | 1317 } // namespace internal |
1235 } // namespace v8 | 1318 } // namespace v8 |
OLD | NEW |