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 | |
583 template <typename Char> | 500 template <typename Char> |
584 static void JoinSparseArrayWithSeparator(FixedArray* elements, | 501 static void JoinSparseArrayWithSeparator(FixedArray* elements, |
585 int elements_length, | 502 int elements_length, |
586 uint32_t array_length, | 503 uint32_t array_length, |
587 String* separator, | 504 String* separator, |
588 Vector<Char> buffer) { | 505 Vector<Char> buffer) { |
589 DisallowHeapAllocation no_gc; | 506 DisallowHeapAllocation no_gc; |
590 int previous_separator_position = 0; | 507 int previous_separator_position = 0; |
591 int separator_length = separator->length(); | 508 int separator_length = separator->length(); |
592 int cursor = 0; | 509 int cursor = 0; |
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1309 SealHandleScope shs(isolate); | 1226 SealHandleScope shs(isolate); |
1310 DCHECK(args.length() == 2); | 1227 DCHECK(args.length() == 2); |
1311 if (!args[0]->IsString()) return isolate->heap()->undefined_value(); | 1228 if (!args[0]->IsString()) return isolate->heap()->undefined_value(); |
1312 if (!args[1]->IsNumber()) return isolate->heap()->undefined_value(); | 1229 if (!args[1]->IsNumber()) return isolate->heap()->undefined_value(); |
1313 if (std::isinf(args.number_at(1))) return isolate->heap()->nan_value(); | 1230 if (std::isinf(args.number_at(1))) return isolate->heap()->nan_value(); |
1314 return __RT_impl_Runtime_StringCharCodeAtRT(args, isolate); | 1231 return __RT_impl_Runtime_StringCharCodeAtRT(args, isolate); |
1315 } | 1232 } |
1316 | 1233 |
1317 } // namespace internal | 1234 } // namespace internal |
1318 } // namespace v8 | 1235 } // namespace v8 |
OLD | NEW |