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

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

Issue 2621393002: Move lang-code checking for case-mapping to C++ from JS (Closed)
Patch Set: make ConvertToUpper as before Created 3 years, 11 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 | « src/js/i18n.js ('k') | 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 <memory> 9 #include <memory>
10 10
(...skipping 992 matching lines...) Expand 10 before | Expand all | Expand 10 after
1003 inline int FindFirstUpperOrNonAscii(Handle<String> s, int length) { 1003 inline int FindFirstUpperOrNonAscii(Handle<String> s, int length) {
1004 for (int index = 0; index < length; ++index) { 1004 for (int index = 0; index < length; ++index) {
1005 uint16_t ch = s->Get(index); 1005 uint16_t ch = s->Get(index);
1006 if (V8_UNLIKELY(IsASCIIUpper(ch) || ch & ~0x7F)) { 1006 if (V8_UNLIKELY(IsASCIIUpper(ch) || ch & ~0x7F)) {
1007 return index; 1007 return index;
1008 } 1008 }
1009 } 1009 }
1010 return length; 1010 return length;
1011 } 1011 }
1012 1012
1013 } // namespace 1013 MUST_USE_RESULT Object* ConvertToLower(Handle<String> s, Isolate* isolate) {
1014
1015 RUNTIME_FUNCTION(Runtime_StringToLowerCaseI18N) {
1016 HandleScope scope(isolate);
1017 DCHECK_EQ(args.length(), 1);
1018 CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
1019
1020 int length = s->length();
1021 s = String::Flatten(s);
1022
1023 if (!s->HasOnlyOneByteChars()) { 1014 if (!s->HasOnlyOneByteChars()) {
1024 // Use a slower implementation for strings with characters beyond U+00FF. 1015 // Use a slower implementation for strings with characters beyond U+00FF.
1025 return LocaleConvertCase(s, isolate, false, ""); 1016 return LocaleConvertCase(s, isolate, false, "");
1026 } 1017 }
1027 1018
1019 int length = s->length();
1020
1028 // We depend here on the invariant that the length of a Latin1 1021 // We depend here on the invariant that the length of a Latin1
1029 // string is invariant under ToLowerCase, and the result always 1022 // string is invariant under ToLowerCase, and the result always
1030 // fits in the Latin1 range in the *root locale*. It does not hold 1023 // fits in the Latin1 range in the *root locale*. It does not hold
1031 // for ToUpperCase even in the root locale. 1024 // for ToUpperCase even in the root locale.
1032 1025
1033 // Scan the string for uppercase and non-ASCII characters for strings 1026 // Scan the string for uppercase and non-ASCII characters for strings
1034 // shorter than a machine-word without any memory allocation overhead. 1027 // shorter than a machine-word without any memory allocation overhead.
1035 // TODO(jshin): Apply this to a longer input by breaking FastAsciiConvert() 1028 // TODO(jshin): Apply this to a longer input by breaking FastAsciiConvert()
1036 // to two parts, one for scanning the prefix with no change and the other for 1029 // to two parts, one for scanning the prefix with no change and the other for
1037 // handling ASCII-only characters. 1030 // handling ASCII-only characters.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1073 const uint16_t* src = flat.ToUC16Vector().start(); 1066 const uint16_t* src = flat.ToUC16Vector().start();
1074 CopyChars(dest, src, index_to_first_unprocessed); 1067 CopyChars(dest, src, index_to_first_unprocessed);
1075 for (int index = index_to_first_unprocessed; index < length; ++index) { 1068 for (int index = index_to_first_unprocessed; index < length; ++index) {
1076 dest[index] = ToLatin1Lower(static_cast<uint16_t>(src[index])); 1069 dest[index] = ToLatin1Lower(static_cast<uint16_t>(src[index]));
1077 } 1070 }
1078 } 1071 }
1079 1072
1080 return *result; 1073 return *result;
1081 } 1074 }
1082 1075
1083 RUNTIME_FUNCTION(Runtime_StringToUpperCaseI18N) { 1076 MUST_USE_RESULT Object* ConvertToUpper(Handle<String> s, Isolate* isolate) {
1084 HandleScope scope(isolate);
1085 DCHECK_EQ(args.length(), 1);
1086 CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
1087
1088 int32_t length = s->length(); 1077 int32_t length = s->length();
1089 s = String::Flatten(s);
1090
1091 if (s->HasOnlyOneByteChars() && length > 0) { 1078 if (s->HasOnlyOneByteChars() && length > 0) {
1092 Handle<SeqOneByteString> result = 1079 Handle<SeqOneByteString> result =
1093 isolate->factory()->NewRawOneByteString(length).ToHandleChecked(); 1080 isolate->factory()->NewRawOneByteString(length).ToHandleChecked();
1094 1081
1095 int sharp_s_count; 1082 int sharp_s_count;
1096 bool is_result_single_byte; 1083 bool is_result_single_byte;
1097 { 1084 {
1098 DisallowHeapAllocation no_gc; 1085 DisallowHeapAllocation no_gc;
1099 String::FlatContent flat = s->GetFlatContent(); 1086 String::FlatContent flat = s->GetFlatContent();
1100 uint8_t* dest = result->GetChars(); 1087 uint8_t* dest = result->GetChars();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1140 } else { 1127 } else {
1141 ToUpperWithSharpS(flat.ToUC16Vector(), result); 1128 ToUpperWithSharpS(flat.ToUC16Vector(), result);
1142 } 1129 }
1143 1130
1144 return *result; 1131 return *result;
1145 } 1132 }
1146 1133
1147 return LocaleConvertCase(s, isolate, true, ""); 1134 return LocaleConvertCase(s, isolate, true, "");
1148 } 1135 }
1149 1136
1137 MUST_USE_RESULT Object* ConvertCase(Handle<String> s, bool is_upper,
1138 Isolate* isolate) {
1139 return is_upper ? ConvertToUpper(s, isolate) : ConvertToLower(s, isolate);
1140 }
1141
1142 } // namespace
1143
1144 RUNTIME_FUNCTION(Runtime_StringToLowerCaseI18N) {
1145 HandleScope scope(isolate);
1146 DCHECK_EQ(args.length(), 1);
1147 CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
1148 s = String::Flatten(s);
1149 return ConvertToLower(s, isolate);
1150 }
1151
1152 RUNTIME_FUNCTION(Runtime_StringToUpperCaseI18N) {
1153 HandleScope scope(isolate);
1154 DCHECK_EQ(args.length(), 1);
1155 CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
1156 s = String::Flatten(s);
1157 return ConvertToUpper(s, isolate);
1158 }
1159
1150 RUNTIME_FUNCTION(Runtime_StringLocaleConvertCase) { 1160 RUNTIME_FUNCTION(Runtime_StringLocaleConvertCase) {
1151 HandleScope scope(isolate); 1161 HandleScope scope(isolate);
1152 DCHECK_EQ(args.length(), 3); 1162 DCHECK_EQ(args.length(), 3);
1153 CONVERT_ARG_HANDLE_CHECKED(String, s, 0); 1163 CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
1154 CONVERT_BOOLEAN_ARG_CHECKED(is_upper, 1); 1164 CONVERT_BOOLEAN_ARG_CHECKED(is_upper, 1);
1155 CONVERT_ARG_HANDLE_CHECKED(SeqOneByteString, lang, 2); 1165 CONVERT_ARG_HANDLE_CHECKED(String, lang_arg, 2);
jungshik at Google 2017/01/11 19:11:22 From i18n.js, a string "literal" ( e.g. "el", "tr"
1156 1166
1157 // All the languages requiring special handling ("az", "el", "lt", "tr") 1167 DCHECK(lang_arg->length() <= 3);
1158 // have a 2-letter language code. 1168 lang_arg = String::Flatten(lang_arg);
1159 DCHECK(lang->length() == 2); 1169
1160 uint8_t lang_str[3]; 1170 // All the languages requiring special-handling have two-letter codes.
1161 memcpy(lang_str, lang->GetChars(), 2); 1171 if (V8_UNLIKELY(lang_arg->length() > 2))
1162 lang_str[2] = 0; 1172 return ConvertCase(s, is_upper, isolate);
1173
1174 char c1, c2;
1175 {
1176 DisallowHeapAllocation no_gc;
1177 String::FlatContent lang = lang_arg->GetFlatContent();
1178 c1 = lang.Get(0);
1179 c2 = lang.Get(1);
1180 }
1163 s = String::Flatten(s); 1181 s = String::Flatten(s);
1164 // TODO(jshin): Consider adding a fast path for ASCII or Latin-1. The fastpath 1182 // TODO(jshin): Consider adding a fast path for ASCII or Latin-1. The fastpath
1165 // in the root locale needs to be adjusted for az, lt and tr because even case 1183 // in the root locale needs to be adjusted for az, lt and tr because even case
1166 // mapping of ASCII range characters are different in those locales. 1184 // mapping of ASCII range characters are different in those locales.
1167 // Greek (el) does not require any adjustment, though. 1185 // Greek (el) does not require any adjustment.
1168 return LocaleConvertCase(s, isolate, is_upper, 1186 if (V8_UNLIKELY(c1 == 't' && c2 == 'r'))
1169 reinterpret_cast<const char*>(lang_str)); 1187 return LocaleConvertCase(s, isolate, is_upper, "tr");
1188 if (V8_UNLIKELY(c1 == 'e' && c2 == 'l'))
1189 return LocaleConvertCase(s, isolate, is_upper, "el");
1190 if (V8_UNLIKELY(c1 == 'l' && c2 == 't'))
1191 return LocaleConvertCase(s, isolate, is_upper, "lt");
1192 if (V8_UNLIKELY(c1 == 'a' && c2 == 'z'))
1193 return LocaleConvertCase(s, isolate, is_upper, "az");
1194
1195 return ConvertCase(s, is_upper, isolate);
1170 } 1196 }
1171 1197
1172 RUNTIME_FUNCTION(Runtime_DateCacheVersion) { 1198 RUNTIME_FUNCTION(Runtime_DateCacheVersion) {
1173 HandleScope scope(isolate); 1199 HandleScope scope(isolate);
1174 DCHECK_EQ(0, args.length()); 1200 DCHECK_EQ(0, args.length());
1175 if (isolate->serializer_enabled()) return isolate->heap()->undefined_value(); 1201 if (isolate->serializer_enabled()) return isolate->heap()->undefined_value();
1176 if (!isolate->eternal_handles()->Exists(EternalHandles::DATE_CACHE_VERSION)) { 1202 if (!isolate->eternal_handles()->Exists(EternalHandles::DATE_CACHE_VERSION)) {
1177 Handle<FixedArray> date_cache_version = 1203 Handle<FixedArray> date_cache_version =
1178 isolate->factory()->NewFixedArray(1, TENURED); 1204 isolate->factory()->NewFixedArray(1, TENURED);
1179 date_cache_version->set(0, Smi::kZero); 1205 date_cache_version->set(0, Smi::kZero);
1180 isolate->eternal_handles()->CreateSingleton( 1206 isolate->eternal_handles()->CreateSingleton(
1181 isolate, *date_cache_version, EternalHandles::DATE_CACHE_VERSION); 1207 isolate, *date_cache_version, EternalHandles::DATE_CACHE_VERSION);
1182 } 1208 }
1183 Handle<FixedArray> date_cache_version = 1209 Handle<FixedArray> date_cache_version =
1184 Handle<FixedArray>::cast(isolate->eternal_handles()->GetSingleton( 1210 Handle<FixedArray>::cast(isolate->eternal_handles()->GetSingleton(
1185 EternalHandles::DATE_CACHE_VERSION)); 1211 EternalHandles::DATE_CACHE_VERSION));
1186 return date_cache_version->get(0); 1212 return date_cache_version->get(0);
1187 } 1213 }
1188 1214
1189 } // namespace internal 1215 } // namespace internal
1190 } // namespace v8 1216 } // namespace v8
1191 1217
1192 #endif // V8_I18N_SUPPORT 1218 #endif // V8_I18N_SUPPORT
OLDNEW
« no previous file with comments | « src/js/i18n.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698