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 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
550 DisallowHeapAllocation no_gc; | 550 DisallowHeapAllocation no_gc; |
551 | 551 |
552 uc16* sink = answer->GetChars(); | 552 uc16* sink = answer->GetChars(); |
553 #ifdef DEBUG | 553 #ifdef DEBUG |
554 uc16* end = sink + length; | 554 uc16* end = sink + length; |
555 #endif | 555 #endif |
556 | 556 |
557 RUNTIME_ASSERT(fixed_array->get(0)->IsString()); | 557 RUNTIME_ASSERT(fixed_array->get(0)->IsString()); |
558 String* first = String::cast(fixed_array->get(0)); | 558 String* first = String::cast(fixed_array->get(0)); |
559 String* separator_raw = *separator; | 559 String* separator_raw = *separator; |
| 560 |
560 int first_length = first->length(); | 561 int first_length = first->length(); |
561 String::WriteToFlat(first, sink, 0, first_length); | 562 String::WriteToFlat(first, sink, 0, first_length); |
562 sink += first_length; | 563 sink += first_length; |
563 | 564 |
564 for (int i = 1; i < array_length; i++) { | 565 for (int i = 1; i < array_length; i++) { |
565 DCHECK(sink + separator_length <= end); | 566 DCHECK(sink + separator_length <= end); |
566 String::WriteToFlat(separator_raw, sink, 0, separator_length); | 567 String::WriteToFlat(separator_raw, sink, 0, separator_length); |
567 sink += separator_length; | 568 sink += separator_length; |
568 | 569 |
569 RUNTIME_ASSERT(fixed_array->get(i)->IsString()); | 570 RUNTIME_ASSERT(fixed_array->get(i)->IsString()); |
570 String* element = String::cast(fixed_array->get(i)); | 571 String* element = String::cast(fixed_array->get(i)); |
571 int element_length = element->length(); | 572 int element_length = element->length(); |
572 DCHECK(sink + element_length <= end); | 573 DCHECK(sink + element_length <= end); |
573 String::WriteToFlat(element, sink, 0, element_length); | 574 String::WriteToFlat(element, sink, 0, element_length); |
574 sink += element_length; | 575 sink += element_length; |
575 } | 576 } |
576 DCHECK(sink == end); | 577 DCHECK(sink == end); |
577 | 578 |
578 // Use %_FastOneByteArrayJoin instead. | 579 // Use %_FastOneByteArrayJoin instead. |
579 DCHECK(!answer->IsOneByteRepresentation()); | 580 DCHECK(!answer->IsOneByteRepresentation()); |
580 return *answer; | 581 return *answer; |
581 } | 582 } |
582 | 583 |
| 584 template <typename sinkchar> |
| 585 static void WriteRepeatToFlat(String* src, Vector<sinkchar> buffer, int cursor, |
| 586 int repeat, int length) { |
| 587 if (repeat == 0) return; |
| 588 |
| 589 sinkchar* start = &buffer[cursor]; |
| 590 String::WriteToFlat<sinkchar>(src, start, 0, length); |
| 591 |
| 592 int done = 1; |
| 593 sinkchar* next = start + length; |
| 594 |
| 595 while (done < repeat) { |
| 596 int block = Min(done, repeat - done); |
| 597 int block_chars = block * length; |
| 598 CopyChars(next, start, block_chars); |
| 599 next += block_chars; |
| 600 done += block; |
| 601 } |
| 602 } |
| 603 |
583 template <typename Char> | 604 template <typename Char> |
584 static void JoinSparseArrayWithSeparator(FixedArray* elements, | 605 static void JoinSparseArrayWithSeparator(FixedArray* elements, |
585 int elements_length, | 606 int elements_length, |
586 uint32_t array_length, | 607 uint32_t array_length, |
587 String* separator, | 608 String* separator, |
588 Vector<Char> buffer) { | 609 Vector<Char> buffer) { |
589 DisallowHeapAllocation no_gc; | 610 DisallowHeapAllocation no_gc; |
590 int previous_separator_position = 0; | 611 int previous_separator_position = 0; |
591 int separator_length = separator->length(); | 612 int separator_length = separator->length(); |
| 613 DCHECK_LT(0, separator_length); |
592 int cursor = 0; | 614 int cursor = 0; |
593 for (int i = 0; i < elements_length; i += 2) { | 615 for (int i = 0; i < elements_length; i += 2) { |
594 int position = NumberToInt32(elements->get(i)); | 616 int position = NumberToInt32(elements->get(i)); |
595 String* string = String::cast(elements->get(i + 1)); | 617 String* string = String::cast(elements->get(i + 1)); |
596 int string_length = string->length(); | 618 int string_length = string->length(); |
597 if (string->length() > 0) { | 619 if (string->length() > 0) { |
598 while (previous_separator_position < position) { | 620 int repeat = position - previous_separator_position; |
599 String::WriteToFlat<Char>(separator, &buffer[cursor], 0, | 621 WriteRepeatToFlat<Char>(separator, buffer, cursor, repeat, |
600 separator_length); | 622 separator_length); |
601 cursor += separator_length; | 623 cursor += repeat * separator_length; |
602 previous_separator_position++; | 624 previous_separator_position = position; |
603 } | |
604 String::WriteToFlat<Char>(string, &buffer[cursor], 0, string_length); | 625 String::WriteToFlat<Char>(string, &buffer[cursor], 0, string_length); |
605 cursor += string->length(); | 626 cursor += string->length(); |
606 } | 627 } |
607 } | 628 } |
608 if (separator_length > 0) { | 629 |
609 // Array length must be representable as a signed 32-bit number, | 630 int last_array_index = static_cast<int>(array_length - 1); |
610 // otherwise the total string length would have been too large. | 631 // Array length must be representable as a signed 32-bit number, |
611 DCHECK(array_length <= 0x7fffffff); // Is int32_t. | 632 // otherwise the total string length would have been too large. |
612 int last_array_index = static_cast<int>(array_length - 1); | 633 DCHECK(array_length <= 0x7fffffff); // Is int32_t. |
613 while (previous_separator_position < last_array_index) { | 634 int repeat = last_array_index - previous_separator_position; |
614 String::WriteToFlat<Char>(separator, &buffer[cursor], 0, | 635 WriteRepeatToFlat<Char>(separator, buffer, cursor, repeat, separator_length); |
615 separator_length); | 636 cursor += repeat * separator_length; |
616 cursor += separator_length; | |
617 previous_separator_position++; | |
618 } | |
619 } | |
620 DCHECK(cursor <= buffer.length()); | 637 DCHECK(cursor <= buffer.length()); |
621 } | 638 } |
622 | 639 |
623 | 640 |
624 RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) { | 641 RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) { |
625 HandleScope scope(isolate); | 642 HandleScope scope(isolate); |
626 DCHECK(args.length() == 3); | 643 DCHECK(args.length() == 3); |
627 CONVERT_ARG_HANDLE_CHECKED(JSArray, elements_array, 0); | 644 CONVERT_ARG_HANDLE_CHECKED(JSArray, elements_array, 0); |
628 CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]); | 645 CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]); |
629 CONVERT_ARG_HANDLE_CHECKED(String, separator, 2); | 646 CONVERT_ARG_HANDLE_CHECKED(String, separator, 2); |
(...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1302 SealHandleScope shs(isolate); | 1319 SealHandleScope shs(isolate); |
1303 DCHECK(args.length() == 2); | 1320 DCHECK(args.length() == 2); |
1304 if (!args[0]->IsString()) return isolate->heap()->undefined_value(); | 1321 if (!args[0]->IsString()) return isolate->heap()->undefined_value(); |
1305 if (!args[1]->IsNumber()) return isolate->heap()->undefined_value(); | 1322 if (!args[1]->IsNumber()) return isolate->heap()->undefined_value(); |
1306 if (std::isinf(args.number_at(1))) return isolate->heap()->nan_value(); | 1323 if (std::isinf(args.number_at(1))) return isolate->heap()->nan_value(); |
1307 return __RT_impl_Runtime_StringCharCodeAtRT(args, isolate); | 1324 return __RT_impl_Runtime_StringCharCodeAtRT(args, isolate); |
1308 } | 1325 } |
1309 | 1326 |
1310 } // namespace internal | 1327 } // namespace internal |
1311 } // namespace v8 | 1328 } // namespace v8 |
OLD | NEW |