Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/runtime/runtime-i18n.cc

Issue 1875263006: Experimental CL on top of https://codereview.chromium.org/1812673005/ (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@caseconv
Patch Set: another tweak: greek support added Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "src/api.h" 9 #include "src/api.h"
10 #include "src/api-natives.h" 10 #include "src/api-natives.h"
(...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 } else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) { 746 } else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) {
747 return *isolate->factory()->NewStringFromStaticChars("kana"); 747 return *isolate->factory()->NewStringFromStaticChars("kana");
748 } else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) { 748 } else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) {
749 return *isolate->factory()->NewStringFromStaticChars("ideo"); 749 return *isolate->factory()->NewStringFromStaticChars("ideo");
750 } else { 750 } else {
751 return *isolate->factory()->NewStringFromStaticChars("unknown"); 751 return *isolate->factory()->NewStringFromStaticChars("unknown");
752 } 752 }
753 } 753 }
754 754
755 namespace { 755 namespace {
756 #if 0
756 inline void LocaleConvertCaseHelper(icu::UnicodeString* s, bool is_to_upper, 757 inline void LocaleConvertCaseHelper(icu::UnicodeString* s, bool is_to_upper,
757 const icu::Locale& locale) { 758 const icu::Locale& locale) {
758 if (is_to_upper) 759 if (is_to_upper)
759 s->toUpper(locale); 760 s->toUpper(locale);
760 else 761 else
761 s->toLower(locale); 762 s->toLower(locale);
762 } 763 }
764 #endif
763 void ConvertCaseWithTransliterator(icu::UnicodeString* input, 765 void ConvertCaseWithTransliterator(icu::UnicodeString* input,
764 const char* transliterator_id) { 766 const char* transliterator_id) {
765 UErrorCode status = U_ZERO_ERROR; 767 UErrorCode status = U_ZERO_ERROR;
766 base::SmartPointer<icu::Transliterator> translit( 768 base::SmartPointer<icu::Transliterator> translit(
767 icu::Transliterator::createInstance( 769 icu::Transliterator::createInstance(
768 icu::UnicodeString(transliterator_id, -1, US_INV), UTRANS_FORWARD, 770 icu::UnicodeString(transliterator_id, -1, US_INV), UTRANS_FORWARD,
769 status)); 771 status));
770 if (U_FAILURE(status)) return; 772 if (U_FAILURE(status)) return;
771 translit->transliterate(*input); 773 translit->transliterate(*input);
772 } 774 }
773 775
774 MUST_USE_RESULT Object* LocaleConvertCase(Handle<String> s, Isolate* isolate, 776 MUST_USE_RESULT Object* LocaleConvertCase(Handle<String> s, Isolate* isolate,
775 bool is_to_upper, int locale_id) { 777 bool is_to_upper, int locale_id) {
776 static const char* conversion_locales[] = { 778 static const char* conversion_locales[] = {
777 "az", "el", "lt", "tr", 779 "az", "el", "lt", "tr",
778 }; 780 };
779 RUNTIME_ASSERT(locale_id >= -1 && 781 RUNTIME_ASSERT(locale_id >= -1 &&
780 locale_id < static_cast<int>(arraysize(conversion_locales))); 782 locale_id < static_cast<int>(arraysize(conversion_locales)));
781 int32_t length = s->length(); 783 int32_t length = s->length();
782 icu::UnicodeString converted; 784 base::SmartArrayPointer<uc16> sap;
785 const UChar* src;
786 Handle<SeqTwoByteString> result =
787 isolate->factory()->NewRawTwoByteString(length).ToHandleChecked();
783 { 788 {
784 DisallowHeapAllocation no_gc; 789 DisallowHeapAllocation no_gc;
785 DCHECK(s->IsFlat()); 790 DCHECK(s->IsFlat());
786 String::FlatContent flat = s->GetFlatContent(); 791 String::FlatContent flat = s->GetFlatContent();
787
788 const UChar* src;
789 if (flat.IsOneByte()) { 792 if (flat.IsOneByte()) {
790 base::SmartArrayPointer<uc16> sap = s->ToWideCString(); 793 sap = s->ToWideCString();
791 src = reinterpret_cast<const UChar*>(sap.get()); 794 src = reinterpret_cast<const UChar*>(sap.get());
792 converted = icu::UnicodeString(src, length);
793 } else { 795 } else {
796 // Will the memory pointed to by |src| be available reliably
797 // outside the block? Thai, will it survive 'gc' that may
798 // be invoked when |result| is "relloced" below?
794 src = reinterpret_cast<const UChar*>(flat.ToUC16Vector().start()); 799 src = reinterpret_cast<const UChar*>(flat.ToUC16Vector().start());
jungshik at Google 2016/04/14 00:32:34 adamk@ and littledan@: Can you answer my question
adamk 2016/04/14 01:56:35 What you're doing here is basically defeating the
795 converted = icu::UnicodeString(src, length);
796 } 800 }
797 } 801 }
798 802
799 if (locale_id == -1) { 803 if (V8_LIKELY(locale_id != 1 || !is_to_upper)) {
800 LocaleConvertCaseHelper(&converted, is_to_upper, icu::Locale::getRoot()); 804 typedef int32_t (*case_conversion_fn)(
801 } else if (V8_UNLIKELY(locale_id == 1 && is_to_upper)) { 805 UChar * dest, int32_t destCapacity, const UChar* src, int32_t srcLength,
802 // TODO(jshin): Once http://bugs.icu-project.org/trac/ticket/10582 is 806 const char* locale, UErrorCode* pErrorCode);
803 // fixed, remove this special-casing for uppercasing in Greek(el) locale. 807 case_conversion_fn fn = is_to_upper ? u_strToUpper : u_strToLower;
804 // This is ~500 times slower than using the case conversion API. 808
805 ConvertCaseWithTransliterator(&converted, "el-Upper"); 809 int32_t target_length = length;
806 } else { 810 const char* locale = locale_id == -1 ? "" : conversion_locales[locale_id];
807 LocaleConvertCaseHelper(&converted, is_to_upper, 811 UErrorCode error;
808 icu::Locale(conversion_locales[locale_id])); 812 do {
813 error = U_ZERO_ERROR;
814 target_length = fn(reinterpret_cast<UChar*>(result->GetChars()),
815 target_length, src, length, locale, &error);
816 result->set_length(target_length);
817 } while (error == U_BUFFER_OVERFLOW_ERROR);
818 return U_SUCCESS(error) ? *result : *s;
809 } 819 }
810 820
811 Handle<String> result; 821 icu::UnicodeString converted(false, src, length);
822 ConvertCaseWithTransliterator(&converted, "el-Upper");
823 Handle<String> greek_result;
812 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 824 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
813 isolate, result, 825 isolate, greek_result,
814 isolate->factory()->NewStringFromTwoByte(Vector<const uint16_t>( 826 isolate->factory()->NewStringFromTwoByte(Vector<const uint16_t>(
815 reinterpret_cast<const uint16_t*>(converted.getBuffer()), 827 reinterpret_cast<const uint16_t*>(converted.getBuffer()),
816 converted.length()))); 828 converted.length())));
817 return *result; 829 return *greek_result;
818 } 830 }
819 831
820 inline bool IsASCIIUpper(uint16_t ch) { return ch >= 'A' && ch <= 'Z'; } 832 inline bool IsASCIIUpper(uint16_t ch) { return ch >= 'A' && ch <= 'Z'; }
821 833
822 inline uint16_t ToASCIILower(uint16_t ch) { 834 inline uint16_t ToASCIILower(uint16_t ch) {
823 return ch | ((ch >= 'A' && ch <= 'Z') << 5); 835 return ch | ((ch >= 'A' && ch <= 'Z') << 5);
824 } 836 }
825 837
826 inline uint16_t ToASCIIUpper(uint16_t ch) { 838 inline uint16_t ToASCIIUpper(uint16_t ch) {
827 return ch & ~((ch >= 'a' && ch <= 'z') << 5); 839 return ch & ~((ch >= 'a' && ch <= 'z') << 5);
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
970 CONVERT_BOOLEAN_ARG_CHECKED(is_upper, 1); 982 CONVERT_BOOLEAN_ARG_CHECKED(is_upper, 1);
971 CONVERT_NUMBER_CHECKED(int, lang_id, Int32, args[2]); 983 CONVERT_NUMBER_CHECKED(int, lang_id, Int32, args[2]);
972 984
973 return LocaleConvertCase(s, isolate, is_upper, lang_id); 985 return LocaleConvertCase(s, isolate, is_upper, lang_id);
974 } 986 }
975 987
976 } // namespace internal 988 } // namespace internal
977 } // namespace v8 989 } // namespace v8
978 990
979 #endif // V8_I18N_SUPPORT 991 #endif // V8_I18N_SUPPORT
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698