| 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 | 5 |
| 6 #ifdef V8_I18N_SUPPORT | 6 #ifdef V8_I18N_SUPPORT |
| 7 #include "src/runtime/runtime-utils.h" | 7 #include "src/runtime/runtime-utils.h" |
| 8 | 8 |
| 9 #include <memory> |
| 10 |
| 9 #include "src/api.h" | 11 #include "src/api.h" |
| 10 #include "src/api-natives.h" | 12 #include "src/api-natives.h" |
| 11 #include "src/arguments.h" | 13 #include "src/arguments.h" |
| 12 #include "src/factory.h" | 14 #include "src/factory.h" |
| 13 #include "src/i18n.h" | 15 #include "src/i18n.h" |
| 14 #include "src/isolate-inl.h" | 16 #include "src/isolate-inl.h" |
| 15 #include "src/messages.h" | 17 #include "src/messages.h" |
| 16 | 18 |
| 17 #include "unicode/brkiter.h" | 19 #include "unicode/brkiter.h" |
| 18 #include "unicode/calendar.h" | 20 #include "unicode/calendar.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 38 #include "unicode/unistr.h" | 40 #include "unicode/unistr.h" |
| 39 #include "unicode/unum.h" | 41 #include "unicode/unum.h" |
| 40 #include "unicode/uversion.h" | 42 #include "unicode/uversion.h" |
| 41 | 43 |
| 42 | 44 |
| 43 namespace v8 { | 45 namespace v8 { |
| 44 namespace internal { | 46 namespace internal { |
| 45 namespace { | 47 namespace { |
| 46 | 48 |
| 47 const UChar* GetUCharBufferFromFlat(const String::FlatContent& flat, | 49 const UChar* GetUCharBufferFromFlat(const String::FlatContent& flat, |
| 48 base::SmartArrayPointer<uc16>* dest, | 50 std::unique_ptr<uc16[]>* dest, |
| 49 int32_t length) { | 51 int32_t length) { |
| 50 DCHECK(flat.IsFlat()); | 52 DCHECK(flat.IsFlat()); |
| 51 if (flat.IsOneByte()) { | 53 if (flat.IsOneByte()) { |
| 52 if (dest->is_empty()) { | 54 if (!*dest) { |
| 53 dest->Reset(NewArray<uc16>(length)); | 55 dest->reset(NewArray<uc16>(length)); |
| 54 CopyChars(dest->get(), flat.ToOneByteVector().start(), length); | 56 CopyChars(dest->get(), flat.ToOneByteVector().start(), length); |
| 55 } | 57 } |
| 56 return reinterpret_cast<const UChar*>(dest->get()); | 58 return reinterpret_cast<const UChar*>(dest->get()); |
| 57 } else { | 59 } else { |
| 58 return reinterpret_cast<const UChar*>(flat.ToUC16Vector().start()); | 60 return reinterpret_cast<const UChar*>(flat.ToUC16Vector().start()); |
| 59 } | 61 } |
| 60 } | 62 } |
| 61 | 63 |
| 62 } // namespace | 64 } // namespace |
| 63 | 65 |
| (...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 icu::Collator* collator = Collator::UnpackCollator(isolate, collator_holder); | 569 icu::Collator* collator = Collator::UnpackCollator(isolate, collator_holder); |
| 568 if (!collator) return isolate->ThrowIllegalOperation(); | 570 if (!collator) return isolate->ThrowIllegalOperation(); |
| 569 | 571 |
| 570 string1 = String::Flatten(string1); | 572 string1 = String::Flatten(string1); |
| 571 string2 = String::Flatten(string2); | 573 string2 = String::Flatten(string2); |
| 572 DisallowHeapAllocation no_gc; | 574 DisallowHeapAllocation no_gc; |
| 573 int32_t length1 = string1->length(); | 575 int32_t length1 = string1->length(); |
| 574 int32_t length2 = string2->length(); | 576 int32_t length2 = string2->length(); |
| 575 String::FlatContent flat1 = string1->GetFlatContent(); | 577 String::FlatContent flat1 = string1->GetFlatContent(); |
| 576 String::FlatContent flat2 = string2->GetFlatContent(); | 578 String::FlatContent flat2 = string2->GetFlatContent(); |
| 577 base::SmartArrayPointer<uc16> sap1; | 579 std::unique_ptr<uc16[]> sap1; |
| 578 base::SmartArrayPointer<uc16> sap2; | 580 std::unique_ptr<uc16[]> sap2; |
| 579 const UChar* string_val1 = GetUCharBufferFromFlat(flat1, &sap1, length1); | 581 const UChar* string_val1 = GetUCharBufferFromFlat(flat1, &sap1, length1); |
| 580 const UChar* string_val2 = GetUCharBufferFromFlat(flat2, &sap2, length2); | 582 const UChar* string_val2 = GetUCharBufferFromFlat(flat2, &sap2, length2); |
| 581 UErrorCode status = U_ZERO_ERROR; | 583 UErrorCode status = U_ZERO_ERROR; |
| 582 UCollationResult result = | 584 UCollationResult result = |
| 583 collator->compare(string_val1, length1, string_val2, length2, status); | 585 collator->compare(string_val1, length1, string_val2, length2, status); |
| 584 if (U_FAILURE(status)) return isolate->ThrowIllegalOperation(); | 586 if (U_FAILURE(status)) return isolate->ThrowIllegalOperation(); |
| 585 | 587 |
| 586 return *isolate->factory()->NewNumberFromInt(result); | 588 return *isolate->factory()->NewNumberFromInt(result); |
| 587 } | 589 } |
| 588 | 590 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 602 DCHECK(args.length() == 2); | 604 DCHECK(args.length() == 2); |
| 603 | 605 |
| 604 CONVERT_ARG_HANDLE_CHECKED(String, s, 0); | 606 CONVERT_ARG_HANDLE_CHECKED(String, s, 0); |
| 605 CONVERT_NUMBER_CHECKED(int, form_id, Int32, args[1]); | 607 CONVERT_NUMBER_CHECKED(int, form_id, Int32, args[1]); |
| 606 CHECK(form_id >= 0 && | 608 CHECK(form_id >= 0 && |
| 607 static_cast<size_t>(form_id) < arraysize(normalizationForms)); | 609 static_cast<size_t>(form_id) < arraysize(normalizationForms)); |
| 608 | 610 |
| 609 int length = s->length(); | 611 int length = s->length(); |
| 610 s = String::Flatten(s); | 612 s = String::Flatten(s); |
| 611 icu::UnicodeString result; | 613 icu::UnicodeString result; |
| 612 base::SmartArrayPointer<uc16> sap; | 614 std::unique_ptr<uc16[]> sap; |
| 613 UErrorCode status = U_ZERO_ERROR; | 615 UErrorCode status = U_ZERO_ERROR; |
| 614 { | 616 { |
| 615 DisallowHeapAllocation no_gc; | 617 DisallowHeapAllocation no_gc; |
| 616 String::FlatContent flat = s->GetFlatContent(); | 618 String::FlatContent flat = s->GetFlatContent(); |
| 617 const UChar* src = GetUCharBufferFromFlat(flat, &sap, length); | 619 const UChar* src = GetUCharBufferFromFlat(flat, &sap, length); |
| 618 icu::UnicodeString input(false, src, length); | 620 icu::UnicodeString input(false, src, length); |
| 619 // Getting a singleton. Should not free it. | 621 // Getting a singleton. Should not free it. |
| 620 const icu::Normalizer2* normalizer = | 622 const icu::Normalizer2* normalizer = |
| 621 icu::Normalizer2::getInstance(nullptr, normalizationForms[form_id].name, | 623 icu::Normalizer2::getInstance(nullptr, normalizationForms[form_id].name, |
| 622 normalizationForms[form_id].mode, status); | 624 normalizationForms[form_id].mode, status); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 701 if (!break_iterator) return isolate->ThrowIllegalOperation(); | 703 if (!break_iterator) return isolate->ThrowIllegalOperation(); |
| 702 | 704 |
| 703 icu::UnicodeString* u_text = reinterpret_cast<icu::UnicodeString*>( | 705 icu::UnicodeString* u_text = reinterpret_cast<icu::UnicodeString*>( |
| 704 break_iterator_holder->GetInternalField(1)); | 706 break_iterator_holder->GetInternalField(1)); |
| 705 delete u_text; | 707 delete u_text; |
| 706 | 708 |
| 707 int length = text->length(); | 709 int length = text->length(); |
| 708 text = String::Flatten(text); | 710 text = String::Flatten(text); |
| 709 DisallowHeapAllocation no_gc; | 711 DisallowHeapAllocation no_gc; |
| 710 String::FlatContent flat = text->GetFlatContent(); | 712 String::FlatContent flat = text->GetFlatContent(); |
| 711 base::SmartArrayPointer<uc16> sap; | 713 std::unique_ptr<uc16[]> sap; |
| 712 const UChar* text_value = GetUCharBufferFromFlat(flat, &sap, length); | 714 const UChar* text_value = GetUCharBufferFromFlat(flat, &sap, length); |
| 713 u_text = new icu::UnicodeString(text_value, length); | 715 u_text = new icu::UnicodeString(text_value, length); |
| 714 break_iterator_holder->SetInternalField(1, reinterpret_cast<Smi*>(u_text)); | 716 break_iterator_holder->SetInternalField(1, reinterpret_cast<Smi*>(u_text)); |
| 715 | 717 |
| 716 break_iterator->setText(*u_text); | 718 break_iterator->setText(*u_text); |
| 717 | 719 |
| 718 return isolate->heap()->undefined_value(); | 720 return isolate->heap()->undefined_value(); |
| 719 } | 721 } |
| 720 | 722 |
| 721 | 723 |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 813 | 815 |
| 814 // Greek uppercasing has to be done via transliteration. | 816 // Greek uppercasing has to be done via transliteration. |
| 815 // TODO(jshin): Drop this special-casing once ICU's regular case conversion | 817 // TODO(jshin): Drop this special-casing once ICU's regular case conversion |
| 816 // API supports Greek uppercasing. See | 818 // API supports Greek uppercasing. See |
| 817 // http://bugs.icu-project.org/trac/ticket/10582 . | 819 // http://bugs.icu-project.org/trac/ticket/10582 . |
| 818 // In the meantime, if there's no Greek character in |s|, call this | 820 // In the meantime, if there's no Greek character in |s|, call this |
| 819 // function again with the root locale (lang=""). | 821 // function again with the root locale (lang=""). |
| 820 // ICU's C API for transliteration is nasty and we just use C++ API. | 822 // ICU's C API for transliteration is nasty and we just use C++ API. |
| 821 if (V8_UNLIKELY(is_to_upper && lang[0] == 'e' && lang[1] == 'l')) { | 823 if (V8_UNLIKELY(is_to_upper && lang[0] == 'e' && lang[1] == 'l')) { |
| 822 icu::UnicodeString converted; | 824 icu::UnicodeString converted; |
| 823 base::SmartArrayPointer<uc16> sap; | 825 std::unique_ptr<uc16[]> sap; |
| 824 { | 826 { |
| 825 DisallowHeapAllocation no_gc; | 827 DisallowHeapAllocation no_gc; |
| 826 String::FlatContent flat = s->GetFlatContent(); | 828 String::FlatContent flat = s->GetFlatContent(); |
| 827 const UChar* src = GetUCharBufferFromFlat(flat, &sap, src_length); | 829 const UChar* src = GetUCharBufferFromFlat(flat, &sap, src_length); |
| 828 // Starts with the source string (read-only alias with copy-on-write | 830 // Starts with the source string (read-only alias with copy-on-write |
| 829 // semantics) and will be modified to contain the converted result. | 831 // semantics) and will be modified to contain the converted result. |
| 830 // Using read-only alias at first saves one copy operation if | 832 // Using read-only alias at first saves one copy operation if |
| 831 // transliteration does not change the input, which is rather rare. | 833 // transliteration does not change the input, which is rather rare. |
| 832 // Moreover, transliteration takes rather long so that saving one copy | 834 // Moreover, transliteration takes rather long so that saving one copy |
| 833 // helps only a little bit. | 835 // helps only a little bit. |
| 834 converted.setTo(false, src, src_length); | 836 converted.setTo(false, src, src_length); |
| 835 ConvertCaseWithTransliterator(&converted, "el-Upper"); | 837 ConvertCaseWithTransliterator(&converted, "el-Upper"); |
| 836 // If no change is made, just return |s|. | 838 // If no change is made, just return |s|. |
| 837 if (converted.getBuffer() == src) return *s; | 839 if (converted.getBuffer() == src) return *s; |
| 838 } | 840 } |
| 839 RETURN_RESULT_OR_FAILURE( | 841 RETURN_RESULT_OR_FAILURE( |
| 840 isolate, | 842 isolate, |
| 841 isolate->factory()->NewStringFromTwoByte(Vector<const uint16_t>( | 843 isolate->factory()->NewStringFromTwoByte(Vector<const uint16_t>( |
| 842 reinterpret_cast<const uint16_t*>(converted.getBuffer()), | 844 reinterpret_cast<const uint16_t*>(converted.getBuffer()), |
| 843 converted.length()))); | 845 converted.length()))); |
| 844 } | 846 } |
| 845 | 847 |
| 846 auto case_converter = is_to_upper ? u_strToUpper : u_strToLower; | 848 auto case_converter = is_to_upper ? u_strToUpper : u_strToLower; |
| 847 | 849 |
| 848 int32_t dest_length = src_length; | 850 int32_t dest_length = src_length; |
| 849 UErrorCode status; | 851 UErrorCode status; |
| 850 Handle<SeqTwoByteString> result; | 852 Handle<SeqTwoByteString> result; |
| 851 base::SmartArrayPointer<uc16> sap; | 853 std::unique_ptr<uc16[]> sap; |
| 852 | 854 |
| 853 // This is not a real loop. It'll be executed only once (no overflow) or | 855 // This is not a real loop. It'll be executed only once (no overflow) or |
| 854 // twice (overflow). | 856 // twice (overflow). |
| 855 for (int i = 0; i < 2; ++i) { | 857 for (int i = 0; i < 2; ++i) { |
| 856 result = | 858 result = |
| 857 isolate->factory()->NewRawTwoByteString(dest_length).ToHandleChecked(); | 859 isolate->factory()->NewRawTwoByteString(dest_length).ToHandleChecked(); |
| 858 DisallowHeapAllocation no_gc; | 860 DisallowHeapAllocation no_gc; |
| 859 String::FlatContent flat = s->GetFlatContent(); | 861 String::FlatContent flat = s->GetFlatContent(); |
| 860 const UChar* src = GetUCharBufferFromFlat(flat, &sap, src_length); | 862 const UChar* src = GetUCharBufferFromFlat(flat, &sap, src_length); |
| 861 status = U_ZERO_ERROR; | 863 status = U_ZERO_ERROR; |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1145 Handle<FixedArray> date_cache_version = | 1147 Handle<FixedArray> date_cache_version = |
| 1146 Handle<FixedArray>::cast(isolate->eternal_handles()->GetSingleton( | 1148 Handle<FixedArray>::cast(isolate->eternal_handles()->GetSingleton( |
| 1147 EternalHandles::DATE_CACHE_VERSION)); | 1149 EternalHandles::DATE_CACHE_VERSION)); |
| 1148 return date_cache_version->get(0); | 1150 return date_cache_version->get(0); |
| 1149 } | 1151 } |
| 1150 | 1152 |
| 1151 } // namespace internal | 1153 } // namespace internal |
| 1152 } // namespace v8 | 1154 } // namespace v8 |
| 1153 | 1155 |
| 1154 #endif // V8_I18N_SUPPORT | 1156 #endif // V8_I18N_SUPPORT |
| OLD | NEW |