Revision: 16015
Author:   [email protected]
Date:     Thu Aug  1 12:25:27 2013
Log:      Move helper methods from i18n extension into runtime.

BUG=v8:2475
[email protected]

Review URL: https://codereview.chromium.org/21499003
http://code.google.com/p/v8/source/detail?r=16015

Deleted:
 /branches/bleeding_edge/src/extensions/i18n/locale.cc
 /branches/bleeding_edge/src/extensions/i18n/locale.h
Modified:
 /branches/bleeding_edge/src/extensions/i18n/i18n-extension.cc
 /branches/bleeding_edge/src/extensions/i18n/i18n-utils.js
 /branches/bleeding_edge/src/extensions/i18n/locale.js
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/src/runtime.h
 /branches/bleeding_edge/tools/gyp/v8.gyp

=======================================
--- /branches/bleeding_edge/src/extensions/i18n/locale.cc Fri Jul 5 02:52:11 2013
+++ /dev/null
@@ -1,251 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// limitations under the License.
-
-#include "locale.h"
-
-#include <string.h>
-
-#include "unicode/brkiter.h"
-#include "unicode/coll.h"
-#include "unicode/datefmt.h"
-#include "unicode/numfmt.h"
-#include "unicode/uloc.h"
-#include "unicode/uversion.h"
-
-namespace v8_i18n {
-
-void JSCanonicalizeLanguageTag(
-    const v8::FunctionCallbackInfo<v8::Value>& args) {
-  // Expect locale id which is a string.
-  if (args.Length() != 1 || !args[0]->IsString()) {
-    v8::ThrowException(v8::Exception::SyntaxError(
-        v8::String::New("Locale identifier, as a string, is required.")));
-    return;
-  }
-
-  UErrorCode error = U_ZERO_ERROR;
-
-  char icu_result[ULOC_FULLNAME_CAPACITY];
-  int icu_length = 0;
-
-  // Return value which denotes invalid language tag.
-  const char* const kInvalidTag = "invalid-tag";
-
-  v8::String::AsciiValue locale_id(args[0]->ToString());
-  if (*locale_id == NULL) {
-    args.GetReturnValue().Set(v8::String::New(kInvalidTag));
-    return;
-  }
-
-  uloc_forLanguageTag(*locale_id, icu_result, ULOC_FULLNAME_CAPACITY,
-                      &icu_length, &error);
-  if (U_FAILURE(error) || icu_length == 0) {
-    args.GetReturnValue().Set(v8::String::New(kInvalidTag));
-    return;
-  }
-
-  char result[ULOC_FULLNAME_CAPACITY];
-
-  // Force strict BCP47 rules.
- uloc_toLanguageTag(icu_result, result, ULOC_FULLNAME_CAPACITY, TRUE, &error);
-
-  if (U_FAILURE(error)) {
-    args.GetReturnValue().Set(v8::String::New(kInvalidTag));
-    return;
-  }
-
-  args.GetReturnValue().Set(v8::String::New(result));
-}
-
-
-void JSAvailableLocalesOf(const v8::FunctionCallbackInfo<v8::Value>& args) {
-  // Expect service name which is a string.
-  if (args.Length() != 1 || !args[0]->IsString()) {
-    v8::ThrowException(v8::Exception::SyntaxError(
-        v8::String::New("Service identifier, as a string, is required.")));
-    return;
-  }
-
-  const icu::Locale* available_locales = NULL;
-
-  int32_t count = 0;
-  v8::String::AsciiValue service(args[0]->ToString());
-  if (strcmp(*service, "collator") == 0) {
-    available_locales = icu::Collator::getAvailableLocales(count);
-  } else if (strcmp(*service, "numberformat") == 0) {
-    available_locales = icu::NumberFormat::getAvailableLocales(count);
-  } else if (strcmp(*service, "dateformat") == 0) {
-    available_locales = icu::DateFormat::getAvailableLocales(count);
-  } else if (strcmp(*service, "breakiterator") == 0) {
-    available_locales = icu::BreakIterator::getAvailableLocales(count);
-  }
-
-  v8::TryCatch try_catch;
-  UErrorCode error = U_ZERO_ERROR;
-  char result[ULOC_FULLNAME_CAPACITY];
-  v8::Handle<v8::Object> locales = v8::Object::New();
-
-  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;
-    }
-
-    // Index is just a dummy value for the property value.
-    locales->Set(v8::String::New(result), v8::Integer::New(i));
-    if (try_catch.HasCaught()) {
-      // Ignore error, but stop processing and return.
-      break;
-    }
-  }
-
-  args.GetReturnValue().Set(locales);
-}
-
-
-void JSGetDefaultICULocale(const v8::FunctionCallbackInfo<v8::Value>& args) {
-  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)) {
-    args.GetReturnValue().Set(v8::String::New(result));
-    return;
-  }
-
-  args.GetReturnValue().Set(v8::String::New("und"));
-}
-
-
-void JSGetLanguageTagVariants(const v8::FunctionCallbackInfo<v8::Value>& args) {
-  v8::TryCatch try_catch;
-
-  // Expect an array of strings.
-  if (args.Length() != 1 || !args[0]->IsArray()) {
-    v8::ThrowException(v8::Exception::SyntaxError(
-        v8::String::New("Internal error. Expected Array<String>.")));
-    return;
-  }
-
-  v8::Local<v8::Array> input = v8::Local<v8::Array>::Cast(args[0]);
-  v8::Handle<v8::Array> output = v8::Array::New(input->Length());
-  for (unsigned int i = 0; i < input->Length(); ++i) {
-    v8::Local<v8::Value> locale_id = input->Get(i);
-    if (try_catch.HasCaught()) {
-      break;
-    }
-
-    if (!locale_id->IsString()) {
-      v8::ThrowException(v8::Exception::SyntaxError(
-          v8::String::New("Internal error. Array element is missing "
-                          "or it isn't a string.")));
-      return;
-    }
-
-    v8::String::AsciiValue ascii_locale_id(locale_id);
-    if (*ascii_locale_id == NULL) {
-      v8::ThrowException(v8::Exception::SyntaxError(
- v8::String::New("Internal error. Non-ASCII locale identifier.")));
-      return;
-    }
-
-    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(*ascii_locale_id, icu_locale, ULOC_FULLNAME_CAPACITY,
-                        &icu_locale_length, &error);
-    if (U_FAILURE(error) || icu_locale_length == 0) {
-      v8::ThrowException(v8::Exception::SyntaxError(
- v8::String::New("Internal error. Failed to convert locale to ICU.")));
-      return;
-    }
-
-    // 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)) {
-      v8::ThrowException(v8::Exception::SyntaxError(
-          v8::String::New("Internal error. Couldn't generate maximized "
-                          "or base locale.")));
-      return;
-    }
-
-    v8::Handle<v8::Object> result = v8::Object::New();
- result->Set(v8::String::New("maximized"), v8::String::New(base_max_locale));
-    result->Set(v8::String::New("base"), v8::String::New(base_locale));
-    if (try_catch.HasCaught()) {
-      break;
-    }
-
-    output->Set(i, result);
-    if (try_catch.HasCaught()) {
-      break;
-    }
-  }
-
-  args.GetReturnValue().Set(output);
-}
-
-}  // namespace v8_i18n
=======================================
--- /branches/bleeding_edge/src/extensions/i18n/locale.h Wed Jul 3 04:22:29 2013
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// limitations under the License.
-
-#ifndef V8_EXTENSIONS_I18N_SRC_LOCALE_H_
-#define V8_EXTENSIONS_I18N_SRC_LOCALE_H_
-
-#include "unicode/uversion.h"
-#include "v8.h"
-
-namespace v8_i18n {
-
-// Canonicalizes the BCP47 language tag using BCP47 rules.
-// Returns 'invalid-tag' in case input was not well formed.
-void JSCanonicalizeLanguageTag(const v8::FunctionCallbackInfo<v8::Value>& args);
-
-// Returns a list of available locales for collator, date or number formatter.
-void JSAvailableLocalesOf(const v8::FunctionCallbackInfo<v8::Value>& args);
-
-// Returns default ICU locale.
-void JSGetDefaultICULocale(const v8::FunctionCallbackInfo<v8::Value>& args);
-
-// Returns an array of objects, that have maximized and base names of inputs.
-// Unicode extensions are dropped from both.
-// Input: ['zh-TW-u-nu-thai', 'sr']
-// Output: [{maximized: 'zh-Hant-TW', base: 'zh-TW'},
-//          {maximized: 'sr-Cyrl-RS', base: 'sr'}]
-void JSGetLanguageTagVariants(const v8::FunctionCallbackInfo<v8::Value>& args);
-
-}  // namespace v8_i18n
-
-#endif  // V8_EXTENSIONS_I18N_LOCALE_H_
=======================================
--- /branches/bleeding_edge/src/extensions/i18n/i18n-extension.cc Fri Jul 5 02:52:11 2013 +++ /branches/bleeding_edge/src/extensions/i18n/i18n-extension.cc Thu Aug 1 12:25:27 2013
@@ -31,7 +31,6 @@
 #include "break-iterator.h"
 #include "collator.h"
 #include "date-format.h"
-#include "locale.h"
 #include "natives.h"
 #include "number-format.h"

@@ -49,17 +48,6 @@

 v8::Handle<v8::FunctionTemplate> Extension::GetNativeFunction(
     v8::Handle<v8::String> name) {
-  // Standalone, helper methods.
-  if (name->Equals(v8::String::New("NativeJSCanonicalizeLanguageTag"))) {
-    return v8::FunctionTemplate::New(JSCanonicalizeLanguageTag);
-  } else if (name->Equals(v8::String::New("NativeJSAvailableLocalesOf"))) {
-    return v8::FunctionTemplate::New(JSAvailableLocalesOf);
- } else if (name->Equals(v8::String::New("NativeJSGetDefaultICULocale"))) {
-    return v8::FunctionTemplate::New(JSGetDefaultICULocale);
- } else if (name->Equals(v8::String::New("NativeJSGetLanguageTagVariants"))) {
-    return v8::FunctionTemplate::New(JSGetLanguageTagVariants);
-  }
-
   // Date format and parse.
   if (name->Equals(v8::String::New("NativeJSCreateDateTimeFormat"))) {
     return v8::FunctionTemplate::New(DateFormat::JSCreateDateTimeFormat);
=======================================
--- /branches/bleeding_edge/src/extensions/i18n/i18n-utils.js Wed Jul 3 08:30:27 2013 +++ /branches/bleeding_edge/src/extensions/i18n/i18n-utils.js Thu Aug 1 12:25:27 2013
@@ -255,8 +255,6 @@
  * lookup algorithm.
  */
 function lookupMatcher(service, requestedLocales) {
-  native function NativeJSGetDefaultICULocale();
-
   if (service.match(SERVICE_RE) === null) {
     throw new Error('Internal error, wrong service type: ' + service);
   }
@@ -287,7 +285,7 @@

   // Didn't find a match, return default.
   if (DEFAULT_ICU_LOCALE === undefined) {
-    DEFAULT_ICU_LOCALE = NativeJSGetDefaultICULocale();
+    DEFAULT_ICU_LOCALE = %GetDefaultICULocale();
   }

   return {'locale': DEFAULT_ICU_LOCALE, 'extension': '', 'position': -1};
@@ -446,14 +444,12 @@
// Returns Array<Object>, where each object has maximized and base properties.
   // Maximized: zh -> zh-Hans-CN
   // Base: zh-CN-u-ca-gregory -> zh-CN
-  native function NativeJSGetLanguageTagVariants();
-
   // Take care of grandfathered or simple cases.
   if (original === resolved) {
     return original;
   }

-  var locales = NativeJSGetLanguageTagVariants([original, resolved]);
+  var locales = %GetLanguageTagVariants([original, resolved]);
   if (locales[0].maximized !== locales[1].maximized) {
     return resolved;
   }
@@ -471,8 +467,7 @@
  * that is supported. This is required by the spec.
  */
 function getAvailableLocalesOf(service) {
-  native function NativeJSAvailableLocalesOf();
-  var available = NativeJSAvailableLocalesOf(service);
+  var available = %AvailableLocalesOf(service);

   for (var i in available) {
     if (available.hasOwnProperty(i)) {
=======================================
--- /branches/bleeding_edge/src/extensions/i18n/locale.js Wed Jul 3 04:22:29 2013 +++ /branches/bleeding_edge/src/extensions/i18n/locale.js Thu Aug 1 12:25:27 2013
@@ -34,8 +34,6 @@
  * Canonicalizes the language tag, or throws in case the tag is invalid.
  */
 function canonicalizeLanguageTag(localeID) {
-  native function NativeJSCanonicalizeLanguageTag();
-
   // null is typeof 'object' so we have to do extra check.
   if (typeof localeID !== 'string' && typeof localeID !== 'object' ||
       localeID === null) {
@@ -52,7 +50,7 @@
   // ICU bug filled - http://bugs.icu-project.org/trac/ticket/9265.
   // TODO(cira): check if -u-kn-true-kc-true-kh-true still throws after
   // upgrade to ICU 4.9.
-  var tag = NativeJSCanonicalizeLanguageTag(localeString);
+  var tag = %CanonicalizeLanguageTag(localeString);
   if (tag === 'invalid-tag') {
     throw new RangeError('Invalid language tag: ' + localeString);
   }
=======================================
--- /branches/bleeding_edge/src/runtime.cc      Thu Aug  1 01:52:21 2013
+++ /branches/bleeding_edge/src/runtime.cc      Thu Aug  1 12:25:27 2013
@@ -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,200 @@
 #endif  // ENABLE_DEBUGGER_SUPPORT


+#ifdef V8_I18N_SUPPORT
+RUNTIME_FUNCTION(MaybeObject*, Runtime_CanonicalizeLanguageTag) {
+  HandleScope scope(isolate);
+
+  ASSERT(args.length() == 1);
+  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);
+
+  ASSERT(args.length() == 1);
+  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);
+
+  ASSERT(args.length() == 0);
+
+  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);
+
+  ASSERT(args.length() == 1);
+
+  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
=======================================
--- /branches/bleeding_edge/src/runtime.h       Thu Aug  1 01:52:21 2013
+++ /branches/bleeding_edge/src/runtime.h       Thu Aug  1 12:25:27 2013
@@ -534,6 +534,21 @@
 #define RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F)
 #endif

+
+#ifdef V8_I18N_SUPPORT
+#define RUNTIME_FUNCTION_LIST_I18N_SUPPORT(F) \
+  /* i18n support */ \
+  /* Standalone, helper methods. */ \
+  F(CanonicalizeLanguageTag, 1, 1) \
+  F(AvailableLocalesOf, 1, 1) \
+  F(GetDefaultICULocale, 0, 1) \
+  F(GetLanguageTagVariants, 1, 1) \
+
+#else
+#define RUNTIME_FUNCTION_LIST_I18N_SUPPORT(F)
+#endif
+
+
 #ifdef DEBUG
 #define RUNTIME_FUNCTION_LIST_DEBUG(F) \
   /* Testing */ \
@@ -551,7 +566,8 @@
   RUNTIME_FUNCTION_LIST_ALWAYS_1(F) \
   RUNTIME_FUNCTION_LIST_ALWAYS_2(F) \
   RUNTIME_FUNCTION_LIST_DEBUG(F) \
-  RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F)
+  RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F) \
+  RUNTIME_FUNCTION_LIST_I18N_SUPPORT(F)

// ----------------------------------------------------------------------------
 // INLINE_FUNCTION_LIST defines all inlined functions accessed
=======================================
--- /branches/bleeding_edge/tools/gyp/v8.gyp    Wed Jul 31 00:51:46 2013
+++ /branches/bleeding_edge/tools/gyp/v8.gyp    Thu Aug  1 12:25:27 2013
@@ -832,8 +832,6 @@
             '../../src/extensions/i18n/i18n-extension.h',
             '../../src/extensions/i18n/i18n-utils.cc',
             '../../src/extensions/i18n/i18n-utils.h',
-            '../../src/extensions/i18n/locale.cc',
-            '../../src/extensions/i18n/locale.h',
             '../../src/extensions/i18n/number-format.cc',
             '../../src/extensions/i18n/number-format.h',
           ],

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to