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 |