Index: src/runtime/runtime-i18n.cc |
diff --git a/src/runtime/runtime-i18n.cc b/src/runtime/runtime-i18n.cc |
index 2d0c55eb217b1c328e09633d763f9c8d81c7bf8e..ce2650727a24d48c12aa612ffdd9c7c5d09937cf 100644 |
--- a/src/runtime/runtime-i18n.cc |
+++ b/src/runtime/runtime-i18n.cc |
@@ -1010,21 +1010,14 @@ inline int FindFirstUpperOrNonAscii(Handle<String> s, int length) { |
return length; |
} |
-} // namespace |
- |
-RUNTIME_FUNCTION(Runtime_StringToLowerCaseI18N) { |
- HandleScope scope(isolate); |
- DCHECK_EQ(args.length(), 1); |
- CONVERT_ARG_HANDLE_CHECKED(String, s, 0); |
- |
- int length = s->length(); |
- s = String::Flatten(s); |
- |
+MUST_USE_RESULT Object* ConvertToLower(Handle<String> s, Isolate* isolate) { |
if (!s->HasOnlyOneByteChars()) { |
// Use a slower implementation for strings with characters beyond U+00FF. |
return LocaleConvertCase(s, isolate, false, ""); |
} |
+ int length = s->length(); |
+ |
// We depend here on the invariant that the length of a Latin1 |
// string is invariant under ToLowerCase, and the result always |
// fits in the Latin1 range in the *root locale*. It does not hold |
@@ -1080,14 +1073,8 @@ RUNTIME_FUNCTION(Runtime_StringToLowerCaseI18N) { |
return *result; |
} |
-RUNTIME_FUNCTION(Runtime_StringToUpperCaseI18N) { |
- HandleScope scope(isolate); |
- DCHECK_EQ(args.length(), 1); |
- CONVERT_ARG_HANDLE_CHECKED(String, s, 0); |
- |
+MUST_USE_RESULT Object* ConvertToUpper(Handle<String> s, Isolate* isolate) { |
int32_t length = s->length(); |
- s = String::Flatten(s); |
- |
if (s->HasOnlyOneByteChars() && length > 0) { |
Handle<SeqOneByteString> result = |
isolate->factory()->NewRawOneByteString(length).ToHandleChecked(); |
@@ -1147,26 +1134,65 @@ RUNTIME_FUNCTION(Runtime_StringToUpperCaseI18N) { |
return LocaleConvertCase(s, isolate, true, ""); |
} |
+MUST_USE_RESULT Object* ConvertCase(Handle<String> s, bool is_upper, |
+ Isolate* isolate) { |
+ return is_upper ? ConvertToUpper(s, isolate) : ConvertToLower(s, isolate); |
+} |
+ |
+} // namespace |
+ |
+RUNTIME_FUNCTION(Runtime_StringToLowerCaseI18N) { |
+ HandleScope scope(isolate); |
+ DCHECK_EQ(args.length(), 1); |
+ CONVERT_ARG_HANDLE_CHECKED(String, s, 0); |
+ s = String::Flatten(s); |
+ return ConvertToLower(s, isolate); |
+} |
+ |
+RUNTIME_FUNCTION(Runtime_StringToUpperCaseI18N) { |
+ HandleScope scope(isolate); |
+ DCHECK_EQ(args.length(), 1); |
+ CONVERT_ARG_HANDLE_CHECKED(String, s, 0); |
+ s = String::Flatten(s); |
+ return ConvertToUpper(s, isolate); |
+} |
+ |
RUNTIME_FUNCTION(Runtime_StringLocaleConvertCase) { |
HandleScope scope(isolate); |
DCHECK_EQ(args.length(), 3); |
CONVERT_ARG_HANDLE_CHECKED(String, s, 0); |
CONVERT_BOOLEAN_ARG_CHECKED(is_upper, 1); |
- CONVERT_ARG_HANDLE_CHECKED(SeqOneByteString, lang, 2); |
jungshik at Google
2017/01/11 19:11:22
From i18n.js, a string "literal" ( e.g. "el", "tr"
|
- |
- // All the languages requiring special handling ("az", "el", "lt", "tr") |
- // have a 2-letter language code. |
- DCHECK(lang->length() == 2); |
- uint8_t lang_str[3]; |
- memcpy(lang_str, lang->GetChars(), 2); |
- lang_str[2] = 0; |
+ CONVERT_ARG_HANDLE_CHECKED(String, lang_arg, 2); |
+ |
+ DCHECK(lang_arg->length() <= 3); |
+ lang_arg = String::Flatten(lang_arg); |
+ |
+ // All the languages requiring special-handling have two-letter codes. |
+ if (V8_UNLIKELY(lang_arg->length() > 2)) |
+ return ConvertCase(s, is_upper, isolate); |
+ |
+ char c1, c2; |
+ { |
+ DisallowHeapAllocation no_gc; |
+ String::FlatContent lang = lang_arg->GetFlatContent(); |
+ c1 = lang.Get(0); |
+ c2 = lang.Get(1); |
+ } |
s = String::Flatten(s); |
// TODO(jshin): Consider adding a fast path for ASCII or Latin-1. The fastpath |
// in the root locale needs to be adjusted for az, lt and tr because even case |
// mapping of ASCII range characters are different in those locales. |
- // Greek (el) does not require any adjustment, though. |
- return LocaleConvertCase(s, isolate, is_upper, |
- reinterpret_cast<const char*>(lang_str)); |
+ // Greek (el) does not require any adjustment. |
+ if (V8_UNLIKELY(c1 == 't' && c2 == 'r')) |
+ return LocaleConvertCase(s, isolate, is_upper, "tr"); |
+ if (V8_UNLIKELY(c1 == 'e' && c2 == 'l')) |
+ return LocaleConvertCase(s, isolate, is_upper, "el"); |
+ if (V8_UNLIKELY(c1 == 'l' && c2 == 't')) |
+ return LocaleConvertCase(s, isolate, is_upper, "lt"); |
+ if (V8_UNLIKELY(c1 == 'a' && c2 == 'z')) |
+ return LocaleConvertCase(s, isolate, is_upper, "az"); |
+ |
+ return ConvertCase(s, is_upper, isolate); |
} |
RUNTIME_FUNCTION(Runtime_DateCacheVersion) { |