Chromium Code Reviews| 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 "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/api-natives.h" | 10 #include "src/api-natives.h" |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 52 if (dest->is_empty()) { | 52 if (dest->is_empty()) { |
| 53 dest->Reset(NewArray<uc16>(length)); | 53 dest->Reset(NewArray<uc16>(length)); |
| 54 CopyChars(dest->get(), flat.ToOneByteVector().start(), length); | 54 CopyChars(dest->get(), flat.ToOneByteVector().start(), length); |
| 55 } | 55 } |
| 56 return reinterpret_cast<const UChar*>(dest->get()); | 56 return reinterpret_cast<const UChar*>(dest->get()); |
| 57 } else { | 57 } else { |
| 58 return reinterpret_cast<const UChar*>(flat.ToUC16Vector().start()); | 58 return reinterpret_cast<const UChar*>(flat.ToUC16Vector().start()); |
| 59 } | 59 } |
| 60 } | 60 } |
| 61 | 61 |
| 62 base::SmartArrayPointer<char> GetAsciiCString(Handle<String> src) { | |
| 63 String::FlatContent flat = src->GetFlatContent(); | |
| 64 DCHECK(flat.IsFlat()); | |
| 65 int length = src->length(); | |
| 66 char* dest = NewArray<char>(length + 1); | |
| 67 if (flat.IsOneByte()) { | |
| 68 CopyChars(dest, flat.ToOneByteVector().start(), length); | |
| 69 } else { | |
| 70 CopyChars(dest, flat.ToUC16Vector().start(), length); | |
|
Yang
2016/05/30 11:01:49
Do we not care about clamping uc16 characters to c
| |
| 71 } | |
| 72 dest[length] = 0; | |
| 73 return base::SmartArrayPointer<char>(dest); | |
| 74 } | |
| 75 | |
| 62 } // namespace | 76 } // namespace |
| 63 | 77 |
| 64 RUNTIME_FUNCTION(Runtime_CanonicalizeLanguageTag) { | 78 RUNTIME_FUNCTION(Runtime_CanonicalizeLanguageTag) { |
| 65 HandleScope scope(isolate); | 79 HandleScope scope(isolate); |
| 66 Factory* factory = isolate->factory(); | 80 Factory* factory = isolate->factory(); |
| 67 | 81 |
| 68 DCHECK(args.length() == 1); | 82 DCHECK(args.length() == 1); |
| 69 CONVERT_ARG_HANDLE_CHECKED(String, locale_id_str, 0); | 83 CONVERT_ARG_HANDLE_CHECKED(String, tag, 0); |
| 84 // CONVERT_ARG_HANDLE_CHECKED(SeqOneByteString, locale_id_str, 0); | |
|
Yang
2016/05/30 11:01:49
Please remove this line.
| |
| 70 | 85 |
| 71 v8::String::Utf8Value locale_id(v8::Utils::ToLocal(locale_id_str)); | 86 tag = String::Flatten(tag); |
| 72 | |
| 73 // Return value which denotes invalid language tag. | |
| 74 const char* const kInvalidTag = "invalid-tag"; | |
| 75 | |
| 76 UErrorCode error = U_ZERO_ERROR; | 87 UErrorCode error = U_ZERO_ERROR; |
| 77 char icu_result[ULOC_FULLNAME_CAPACITY]; | 88 char icu_result[ULOC_FULLNAME_CAPACITY]; |
| 78 int icu_length = 0; | 89 int icu_length = 0; |
| 79 | 90 { |
| 80 uloc_forLanguageTag(*locale_id, icu_result, ULOC_FULLNAME_CAPACITY, | 91 DisallowHeapAllocation no_gc; |
| 81 &icu_length, &error); | 92 base::SmartArrayPointer<char> locale_id = GetAsciiCString(tag); |
| 93 uloc_forLanguageTag(locale_id.get(), icu_result, ULOC_FULLNAME_CAPACITY, | |
| 94 &icu_length, &error); | |
| 95 } | |
| 96 // Return value which denotes invalid language tag. | |
| 97 const char* const kInvalidTag = "invalid-tag"; | |
| 82 if (U_FAILURE(error) || icu_length == 0) { | 98 if (U_FAILURE(error) || icu_length == 0) { |
| 83 return *factory->NewStringFromAsciiChecked(kInvalidTag); | 99 return *factory->NewStringFromAsciiChecked(kInvalidTag); |
| 84 } | 100 } |
| 85 | 101 |
| 86 char result[ULOC_FULLNAME_CAPACITY]; | 102 char result[ULOC_FULLNAME_CAPACITY]; |
| 87 | 103 |
| 88 // Force strict BCP47 rules. | 104 // Force strict BCP47 rules. |
| 89 uloc_toLanguageTag(icu_result, result, ULOC_FULLNAME_CAPACITY, TRUE, &error); | 105 uloc_toLanguageTag(icu_result, result, ULOC_FULLNAME_CAPACITY, TRUE, &error); |
| 90 | 106 |
| 91 if (U_FAILURE(error)) { | 107 if (U_FAILURE(error)) { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 171 CONVERT_ARG_HANDLE_CHECKED(JSArray, input, 0); | 187 CONVERT_ARG_HANDLE_CHECKED(JSArray, input, 0); |
| 172 | 188 |
| 173 uint32_t length = static_cast<uint32_t>(input->length()->Number()); | 189 uint32_t length = static_cast<uint32_t>(input->length()->Number()); |
| 174 // Set some limit to prevent fuzz tests from going OOM. | 190 // Set some limit to prevent fuzz tests from going OOM. |
| 175 // Can be bumped when callers' requirements change. | 191 // Can be bumped when callers' requirements change. |
| 176 RUNTIME_ASSERT(length < 100); | 192 RUNTIME_ASSERT(length < 100); |
| 177 Handle<FixedArray> output = factory->NewFixedArray(length); | 193 Handle<FixedArray> output = factory->NewFixedArray(length); |
| 178 Handle<Name> maximized = factory->NewStringFromStaticChars("maximized"); | 194 Handle<Name> maximized = factory->NewStringFromStaticChars("maximized"); |
| 179 Handle<Name> base = factory->NewStringFromStaticChars("base"); | 195 Handle<Name> base = factory->NewStringFromStaticChars("base"); |
| 180 for (unsigned int i = 0; i < length; ++i) { | 196 for (unsigned int i = 0; i < length; ++i) { |
| 181 Handle<Object> locale_id; | 197 Handle<Object> entry; |
| 182 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 198 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 183 isolate, locale_id, JSReceiver::GetElement(isolate, input, i)); | 199 isolate, entry, JSReceiver::GetElement(isolate, input, i)); |
| 184 if (!locale_id->IsString()) { | 200 if (!entry->IsString()) { |
| 185 return isolate->Throw(*factory->illegal_argument_string()); | 201 return isolate->Throw(*factory->illegal_argument_string()); |
| 186 } | 202 } |
| 187 | 203 |
| 188 v8::String::Utf8Value utf8_locale_id( | 204 Handle<String> locale_id = String::Flatten(Handle<String>::cast(entry)); |
| 189 v8::Utils::ToLocal(Handle<String>::cast(locale_id))); | |
| 190 | |
| 191 UErrorCode error = U_ZERO_ERROR; | |
| 192 | 205 |
| 193 // Convert from BCP47 to ICU format. | 206 // Convert from BCP47 to ICU format. |
| 194 // de-DE-u-co-phonebk -> de_DE@collation=phonebook | 207 // de-DE-u-co-phonebk -> de_DE@collation=phonebook |
| 195 char icu_locale[ULOC_FULLNAME_CAPACITY]; | 208 char icu_locale[ULOC_FULLNAME_CAPACITY]; |
| 196 int icu_locale_length = 0; | 209 int icu_locale_length = 0; |
| 197 uloc_forLanguageTag(*utf8_locale_id, icu_locale, ULOC_FULLNAME_CAPACITY, | 210 UErrorCode error = U_ZERO_ERROR; |
| 198 &icu_locale_length, &error); | 211 { |
| 199 if (U_FAILURE(error) || icu_locale_length == 0) { | 212 DisallowHeapAllocation no_gc; |
| 200 return isolate->Throw(*factory->illegal_argument_string()); | 213 base::SmartArrayPointer<char> input_locale = GetAsciiCString(locale_id); |
| 214 | |
| 215 uloc_forLanguageTag(input_locale.get(), icu_locale, | |
| 216 ULOC_FULLNAME_CAPACITY, &icu_locale_length, &error); | |
| 217 if (U_FAILURE(error) || icu_locale_length == 0) { | |
| 218 return isolate->Throw(*factory->illegal_argument_string()); | |
| 219 } | |
| 201 } | 220 } |
| 202 | 221 |
| 203 // Maximize the locale. | 222 // Maximize the locale. |
| 204 // de_DE@collation=phonebook -> de_Latn_DE@collation=phonebook | 223 // de_DE@collation=phonebook -> de_Latn_DE@collation=phonebook |
| 205 char icu_max_locale[ULOC_FULLNAME_CAPACITY]; | 224 char icu_max_locale[ULOC_FULLNAME_CAPACITY]; |
| 206 uloc_addLikelySubtags(icu_locale, icu_max_locale, ULOC_FULLNAME_CAPACITY, | 225 uloc_addLikelySubtags(icu_locale, icu_max_locale, ULOC_FULLNAME_CAPACITY, |
| 207 &error); | 226 &error); |
| 208 | 227 |
| 209 // Remove extensions from maximized locale. | 228 // Remove extensions from maximized locale. |
| 210 // de_Latn_DE@collation=phonebook -> de_Latn_DE | 229 // de_Latn_DE@collation=phonebook -> de_Latn_DE |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 393 | 412 |
| 394 | 413 |
| 395 RUNTIME_FUNCTION(Runtime_InternalDateParse) { | 414 RUNTIME_FUNCTION(Runtime_InternalDateParse) { |
| 396 HandleScope scope(isolate); | 415 HandleScope scope(isolate); |
| 397 | 416 |
| 398 DCHECK(args.length() == 2); | 417 DCHECK(args.length() == 2); |
| 399 | 418 |
| 400 CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0); | 419 CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0); |
| 401 CONVERT_ARG_HANDLE_CHECKED(String, date_string, 1); | 420 CONVERT_ARG_HANDLE_CHECKED(String, date_string, 1); |
| 402 | 421 |
| 403 v8::String::Utf8Value utf8_date(v8::Utils::ToLocal(date_string)); | |
| 404 icu::UnicodeString u_date(icu::UnicodeString::fromUTF8(*utf8_date)); | |
| 405 icu::SimpleDateFormat* date_format = | 422 icu::SimpleDateFormat* date_format = |
| 406 DateFormat::UnpackDateFormat(isolate, date_format_holder); | 423 DateFormat::UnpackDateFormat(isolate, date_format_holder); |
| 407 if (!date_format) return isolate->ThrowIllegalOperation(); | 424 if (!date_format) return isolate->ThrowIllegalOperation(); |
| 408 | 425 date_string = String::Flatten(date_string); |
| 409 UErrorCode status = U_ZERO_ERROR; | 426 UDate date; |
| 410 UDate date = date_format->parse(u_date, status); | 427 { |
| 411 if (U_FAILURE(status)) return isolate->heap()->undefined_value(); | 428 DisallowHeapAllocation no_gc; |
| 429 String::FlatContent flat = date_string->GetFlatContent(); | |
| 430 base::SmartArrayPointer<uc16> sap; | |
| 431 int length = date_string->length(); | |
| 432 icu::UnicodeString u_date(false, GetUCharBufferFromFlat(flat, &sap, length), | |
| 433 length); | |
| 434 UErrorCode status = U_ZERO_ERROR; | |
| 435 date = date_format->parse(u_date, status); | |
| 436 if (U_FAILURE(status)) return isolate->heap()->undefined_value(); | |
| 437 } | |
| 412 | 438 |
| 413 Handle<JSDate> result; | 439 Handle<JSDate> result; |
| 414 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 440 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 415 isolate, result, | 441 isolate, result, |
| 416 JSDate::New(isolate->date_function(), isolate->date_function(), | 442 JSDate::New(isolate->date_function(), isolate->date_function(), |
| 417 static_cast<double>(date))); | 443 static_cast<double>(date))); |
| 418 return *result; | 444 return *result; |
| 419 } | 445 } |
| 420 | 446 |
| 421 | 447 |
| (...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1142 // mapping of ASCII range characters are different in those locales. | 1168 // mapping of ASCII range characters are different in those locales. |
| 1143 // Greek (el) does not require any adjustment, though. | 1169 // Greek (el) does not require any adjustment, though. |
| 1144 return LocaleConvertCase(s, isolate, is_upper, | 1170 return LocaleConvertCase(s, isolate, is_upper, |
| 1145 reinterpret_cast<const char*>(lang_str)); | 1171 reinterpret_cast<const char*>(lang_str)); |
| 1146 } | 1172 } |
| 1147 | 1173 |
| 1148 } // namespace internal | 1174 } // namespace internal |
| 1149 } // namespace v8 | 1175 } // namespace v8 |
| 1150 | 1176 |
| 1151 #endif // V8_I18N_SUPPORT | 1177 #endif // V8_I18N_SUPPORT |
| OLD | NEW |