| 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 |