Chromium Code Reviews| Index: src/runtime.cc |
| diff --git a/src/runtime.cc b/src/runtime.cc |
| index 0970d0d92efa5d19986a9d92775eb18f643c88c2..febdc4870aae947d1ce7c8a62eb036e882a7328e 100644 |
| --- a/src/runtime.cc |
| +++ b/src/runtime.cc |
| @@ -66,6 +66,15 @@ |
| #include "v8threads.h" |
| #include "vm-state-inl.h" |
| +#ifdef V8_I18N_SUPPORT |
| +#include "unicode/brkiter.h" |
| +#include "unicode/coll.h" |
| +#include "unicode/datefmt.h" |
| +#include "unicode/numfmt.h" |
| +#include "unicode/uloc.h" |
| +#include "unicode/uversion.h" |
| +#endif |
| + |
| #ifndef _STLP_VENDOR_CSTD |
| // STLPort doesn't import fpclassify and isless into the std namespace. |
| using std::fpclassify; |
| @@ -13362,6 +13371,194 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHeapUsage) { |
| #endif // ENABLE_DEBUGGER_SUPPORT |
| +#ifdef V8_I18N_SUPPORT |
| +RUNTIME_FUNCTION(MaybeObject*, Runtime_CanonicalizeLanguageTag) { |
| + HandleScope scope(isolate); |
| + |
|
Michael Starzinger
2013/08/01 09:58:20
nit: Can we add asserts that check the number of a
|
| + CONVERT_ARG_HANDLE_CHECKED(String, locale_id_str, 0); |
| + |
| + v8::String::Utf8Value locale_id(v8::Utils::ToLocal(locale_id_str)); |
| + |
| + // Return value which denotes invalid language tag. |
| + const char* const kInvalidTag = "invalid-tag"; |
| + |
| + UErrorCode error = U_ZERO_ERROR; |
| + char icu_result[ULOC_FULLNAME_CAPACITY]; |
| + int icu_length = 0; |
| + |
| + uloc_forLanguageTag(*locale_id, icu_result, ULOC_FULLNAME_CAPACITY, |
| + &icu_length, &error); |
| + if (U_FAILURE(error) || icu_length == 0) { |
| + return isolate->heap()->AllocateStringFromOneByte(CStrVector(kInvalidTag)); |
| + } |
| + |
| + char result[ULOC_FULLNAME_CAPACITY]; |
| + |
| + // Force strict BCP47 rules. |
| + uloc_toLanguageTag(icu_result, result, ULOC_FULLNAME_CAPACITY, TRUE, &error); |
| + |
| + if (U_FAILURE(error)) { |
| + return isolate->heap()->AllocateStringFromOneByte(CStrVector(kInvalidTag)); |
| + } |
| + |
| + return isolate->heap()->AllocateStringFromOneByte(CStrVector(result)); |
| +} |
| + |
| + |
| +RUNTIME_FUNCTION(MaybeObject*, Runtime_AvailableLocalesOf) { |
| + HandleScope scope(isolate); |
| + |
|
Michael Starzinger
2013/08/01 09:58:20
Likewise.
|
| + CONVERT_ARG_HANDLE_CHECKED(String, service, 0); |
| + |
| + const icu::Locale* available_locales = NULL; |
| + int32_t count = 0; |
| + |
| + if (service->IsUtf8EqualTo(CStrVector("collator"))) { |
| + available_locales = icu::Collator::getAvailableLocales(count); |
| + } else if (service->IsUtf8EqualTo(CStrVector("numberformat"))) { |
| + available_locales = icu::NumberFormat::getAvailableLocales(count); |
| + } else if (service->IsUtf8EqualTo(CStrVector("dateformat"))) { |
| + available_locales = icu::DateFormat::getAvailableLocales(count); |
| + } else if (service->IsUtf8EqualTo(CStrVector("breakiterator"))) { |
| + available_locales = icu::BreakIterator::getAvailableLocales(count); |
| + } |
| + |
| + UErrorCode error = U_ZERO_ERROR; |
| + char result[ULOC_FULLNAME_CAPACITY]; |
| + Handle<JSObject> locales = |
| + isolate->factory()->NewJSObject(isolate->object_function()); |
| + |
| + for (int32_t i = 0; i < count; ++i) { |
| + const char* icu_name = available_locales[i].getName(); |
| + |
| + error = U_ZERO_ERROR; |
| + // No need to force strict BCP47 rules. |
| + uloc_toLanguageTag(icu_name, result, ULOC_FULLNAME_CAPACITY, FALSE, &error); |
| + if (U_FAILURE(error)) { |
| + // This shouldn't happen, but lets not break the user. |
| + continue; |
| + } |
| + |
| + RETURN_IF_EMPTY_HANDLE(isolate, |
| + JSObject::SetLocalPropertyIgnoreAttributes( |
| + locales, |
| + isolate->factory()->NewStringFromAscii(CStrVector(result)), |
| + isolate->factory()->NewNumber(i), |
| + NONE)); |
| + } |
| + |
| + return *locales; |
| +} |
| + |
| + |
| +RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDefaultICULocale) { |
| + SealHandleScope shs(isolate); |
| + |
|
Michael Starzinger
2013/08/01 09:58:20
Likewise.
|
| + icu::Locale default_locale; |
| + |
| + // Set the locale |
| + char result[ULOC_FULLNAME_CAPACITY]; |
| + UErrorCode status = U_ZERO_ERROR; |
| + uloc_toLanguageTag( |
| + default_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status); |
| + if (U_SUCCESS(status)) { |
| + return isolate->heap()->AllocateStringFromOneByte(CStrVector(result)); |
| + } |
| + |
| + return isolate->heap()->AllocateStringFromOneByte(CStrVector("und")); |
| +} |
| + |
| + |
| +RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLanguageTagVariants) { |
| + HandleScope scope(isolate); |
| + |
|
Michael Starzinger
2013/08/01 09:58:20
Likewise.
|
| + CONVERT_ARG_HANDLE_CHECKED(JSArray, input, 0); |
| + |
| + uint32_t length = static_cast<uint32_t>(input->length()->Number()); |
| + Handle<FixedArray> output = isolate->factory()->NewFixedArray(length); |
| + Handle<Name> maximized = |
| + isolate->factory()->NewStringFromAscii(CStrVector("maximized")); |
| + Handle<Name> base = |
| + isolate->factory()->NewStringFromAscii(CStrVector("base")); |
| + for (unsigned int i = 0; i < length; ++i) { |
| + MaybeObject* maybe_string = input->GetElement(i); |
| + Object* locale_id; |
| + if (!maybe_string->ToObject(&locale_id) || !locale_id->IsString()) { |
| + return isolate->Throw(isolate->heap()->illegal_argument_string()); |
| + } |
| + |
| + v8::String::Utf8Value utf8_locale_id( |
| + v8::Utils::ToLocal(Handle<String>(String::cast(locale_id)))); |
| + |
| + UErrorCode error = U_ZERO_ERROR; |
| + |
| + // Convert from BCP47 to ICU format. |
| + // de-DE-u-co-phonebk -> de_DE@collation=phonebook |
| + char icu_locale[ULOC_FULLNAME_CAPACITY]; |
| + int icu_locale_length = 0; |
| + uloc_forLanguageTag(*utf8_locale_id, icu_locale, ULOC_FULLNAME_CAPACITY, |
| + &icu_locale_length, &error); |
| + if (U_FAILURE(error) || icu_locale_length == 0) { |
| + return isolate->Throw(isolate->heap()->illegal_argument_string()); |
| + } |
| + |
| + // Maximize the locale. |
| + // de_DE@collation=phonebook -> de_Latn_DE@collation=phonebook |
| + char icu_max_locale[ULOC_FULLNAME_CAPACITY]; |
| + uloc_addLikelySubtags( |
| + icu_locale, icu_max_locale, ULOC_FULLNAME_CAPACITY, &error); |
| + |
| + // Remove extensions from maximized locale. |
| + // de_Latn_DE@collation=phonebook -> de_Latn_DE |
| + char icu_base_max_locale[ULOC_FULLNAME_CAPACITY]; |
| + uloc_getBaseName( |
| + icu_max_locale, icu_base_max_locale, ULOC_FULLNAME_CAPACITY, &error); |
| + |
| + // Get original name without extensions. |
| + // de_DE@collation=phonebook -> de_DE |
| + char icu_base_locale[ULOC_FULLNAME_CAPACITY]; |
| + uloc_getBaseName( |
| + icu_locale, icu_base_locale, ULOC_FULLNAME_CAPACITY, &error); |
| + |
| + // Convert from ICU locale format to BCP47 format. |
| + // de_Latn_DE -> de-Latn-DE |
| + char base_max_locale[ULOC_FULLNAME_CAPACITY]; |
| + uloc_toLanguageTag(icu_base_max_locale, base_max_locale, |
| + ULOC_FULLNAME_CAPACITY, FALSE, &error); |
| + |
| + // de_DE -> de-DE |
| + char base_locale[ULOC_FULLNAME_CAPACITY]; |
| + uloc_toLanguageTag( |
| + icu_base_locale, base_locale, ULOC_FULLNAME_CAPACITY, FALSE, &error); |
| + |
| + if (U_FAILURE(error)) { |
| + return isolate->Throw(isolate->heap()->illegal_argument_string()); |
| + } |
| + |
| + Handle<JSObject> result = |
| + isolate->factory()->NewJSObject(isolate->object_function()); |
| + RETURN_IF_EMPTY_HANDLE(isolate, |
| + JSObject::SetLocalPropertyIgnoreAttributes( |
| + result, |
| + maximized, |
| + isolate->factory()->NewStringFromAscii(CStrVector(base_max_locale)), |
| + NONE)); |
| + RETURN_IF_EMPTY_HANDLE(isolate, |
| + JSObject::SetLocalPropertyIgnoreAttributes( |
| + result, |
| + base, |
| + isolate->factory()->NewStringFromAscii(CStrVector(base_locale)), |
| + NONE)); |
| + output->set(i, *result); |
| + } |
| + |
| + Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(output); |
| + result->set_length(Smi::FromInt(length)); |
| + return *result; |
| +} |
| +#endif // V8_I18N_SUPPORT |
| + |
| + |
| // Finds the script object from the script data. NOTE: This operation uses |
| // heap traversal to find the function generated for the source position |
| // for the requested break point. For lazily compiled functions several heap |