Revision: 16239
Author:   joc...@chromium.org
Date:     Tue Aug 20 08:46:36 2013 UTC
Log:      Move i18n break iterator C++ code to runtime

BUG=v8:2745
R=mstarzin...@chromium.org

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

Deleted:
 /branches/bleeding_edge/src/extensions/i18n/break-iterator.cc
 /branches/bleeding_edge/src/extensions/i18n/break-iterator.h
 /branches/bleeding_edge/src/extensions/i18n/i18n-utils.cc
 /branches/bleeding_edge/src/extensions/i18n/i18n-utils.h
Modified:
 /branches/bleeding_edge/src/extensions/i18n/break-iterator.js
 /branches/bleeding_edge/src/extensions/i18n/i18n-extension.cc
 /branches/bleeding_edge/src/extensions/i18n/i18n-extension.h
 /branches/bleeding_edge/src/i18n.cc
 /branches/bleeding_edge/src/i18n.h
 /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/break-iterator.cc Fri Jul 5 09:52:11 2013 UTC
+++ /dev/null
@@ -1,333 +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.
-
-#include "break-iterator.h"
-
-#include <string.h>
-
-#include "i18n-utils.h"
-#include "unicode/brkiter.h"
-#include "unicode/locid.h"
-#include "unicode/rbbi.h"
-
-namespace v8_i18n {
-
-static v8::Handle<v8::Value> ThrowUnexpectedObjectError();
-static icu::UnicodeString* ResetAdoptedText(v8::Handle<v8::Object>,
-                                            v8::Handle<v8::Value>);
-static icu::BreakIterator* InitializeBreakIterator(v8::Handle<v8::String>,
-                                                   v8::Handle<v8::Object>,
-                                                   v8::Handle<v8::Object>);
-static icu::BreakIterator* CreateICUBreakIterator(const icu::Locale&,
-                                                  v8::Handle<v8::Object>);
-static void SetResolvedSettings(const icu::Locale&,
-                                icu::BreakIterator*,
-                                v8::Handle<v8::Object>);
-
-icu::BreakIterator* BreakIterator::UnpackBreakIterator(
-    v8::Handle<v8::Object> obj) {
-  v8::HandleScope handle_scope;
-
-  // v8::ObjectTemplate doesn't have HasInstance method so we can't check
- // if obj is an instance of BreakIterator class. We'll check for a property
-  // that has to be in the object. The same applies to other services, like
-  // Collator and DateTimeFormat.
-  if (obj->HasOwnProperty(v8::String::New("breakIterator"))) {
-    return static_cast<icu::BreakIterator*>(
-        obj->GetAlignedPointerFromInternalField(0));
-  }
-
-  return NULL;
-}
-
-void BreakIterator::DeleteBreakIterator(v8::Isolate* isolate,
-                                        v8::Persistent<v8::Object>* object,
-                                        void* param) {
-  // First delete the hidden C++ object.
-  // Unpacking should never return NULL here. That would only happen if
-  // this method is used as the weak callback for persistent handles not
-  // pointing to a break iterator.
-  v8::HandleScope handle_scope(isolate);
- v8::Local<v8::Object> handle = v8::Local<v8::Object>::New(isolate, *object);
-  delete UnpackBreakIterator(handle);
-
-  delete static_cast<icu::UnicodeString*>(
-      handle->GetAlignedPointerFromInternalField(1));
-
-  // Then dispose of the persistent handle to JS object.
-  object->Dispose(isolate);
-}
-
-
-// Throws a JavaScript exception.
-static v8::Handle<v8::Value> ThrowUnexpectedObjectError() {
-  // Returns undefined, and schedules an exception to be thrown.
-  return v8::ThrowException(v8::Exception::Error(
-      v8::String::New("BreakIterator method called on an object "
-                      "that is not a BreakIterator.")));
-}
-
-
-// Deletes the old value and sets the adopted text in corresponding
-// JavaScript object.
-icu::UnicodeString* ResetAdoptedText(
-    v8::Handle<v8::Object> obj, v8::Handle<v8::Value> value) {
-  // Get the previous value from the internal field.
-  icu::UnicodeString* text = static_cast<icu::UnicodeString*>(
-      obj->GetAlignedPointerFromInternalField(1));
-  delete text;
-
-  // Assign new value to the internal pointer.
-  v8::String::Value text_value(value);
-  text = new icu::UnicodeString(
-      reinterpret_cast<const UChar*>(*text_value), text_value.length());
-  obj->SetAlignedPointerInInternalField(1, text);
-
-  // Return new unicode string pointer.
-  return text;
-}
-
-void BreakIterator::JSInternalBreakIteratorAdoptText(
-    const v8::FunctionCallbackInfo<v8::Value>& args) {
-  if (args.Length() != 2 || !args[0]->IsObject() || !args[1]->IsString()) {
-    v8::ThrowException(v8::Exception::Error(
-        v8::String::New(
-            "Internal error. Iterator and text have to be specified.")));
-    return;
-  }
-
- icu::BreakIterator* break_iterator = UnpackBreakIterator(args[0]->ToObject());
-  if (!break_iterator) {
-    ThrowUnexpectedObjectError();
-    return;
-  }
-
-  break_iterator->setText(*ResetAdoptedText(args[0]->ToObject(), args[1]));
-}
-
-void BreakIterator::JSInternalBreakIteratorFirst(
-    const v8::FunctionCallbackInfo<v8::Value>& args) {
- icu::BreakIterator* break_iterator = UnpackBreakIterator(args[0]->ToObject());
-  if (!break_iterator) {
-    ThrowUnexpectedObjectError();
-    return;
-  }
-
-  args.GetReturnValue().Set(static_cast<int32_t>(break_iterator->first()));
-}
-
-void BreakIterator::JSInternalBreakIteratorNext(
-    const v8::FunctionCallbackInfo<v8::Value>& args) {
- icu::BreakIterator* break_iterator = UnpackBreakIterator(args[0]->ToObject());
-  if (!break_iterator) {
-    ThrowUnexpectedObjectError();
-    return;
-  }
-
-  args.GetReturnValue().Set(static_cast<int32_t>(break_iterator->next()));
-}
-
-void BreakIterator::JSInternalBreakIteratorCurrent(
-    const v8::FunctionCallbackInfo<v8::Value>& args) {
- icu::BreakIterator* break_iterator = UnpackBreakIterator(args[0]->ToObject());
-  if (!break_iterator) {
-    ThrowUnexpectedObjectError();
-    return;
-  }
-
- args.GetReturnValue().Set(static_cast<int32_t>(break_iterator->current()));
-}
-
-void BreakIterator::JSInternalBreakIteratorBreakType(
-    const v8::FunctionCallbackInfo<v8::Value>& args) {
- icu::BreakIterator* break_iterator = UnpackBreakIterator(args[0]->ToObject());
-  if (!break_iterator) {
-    ThrowUnexpectedObjectError();
-    return;
-  }
-
-  // TODO(cira): Remove cast once ICU fixes base BreakIterator class.
-  icu::RuleBasedBreakIterator* rule_based_iterator =
-      static_cast<icu::RuleBasedBreakIterator*>(break_iterator);
-  int32_t status = rule_based_iterator->getRuleStatus();
-  // Keep return values in sync with JavaScript BreakType enum.
-  v8::Handle<v8::String> result;
-  if (status >= UBRK_WORD_NONE && status < UBRK_WORD_NONE_LIMIT) {
-    result = v8::String::New("none");
- } else if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) {
-    result = v8::String::New("number");
- } else if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) {
-    result = v8::String::New("letter");
-  } else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) {
-    result = v8::String::New("kana");
-  } else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) {
-    result = v8::String::New("ideo");
-  } else {
-    result = v8::String::New("unknown");
-  }
-  args.GetReturnValue().Set(result);
-}
-
-void BreakIterator::JSCreateBreakIterator(
-    const v8::FunctionCallbackInfo<v8::Value>& args) {
-  if (args.Length() != 3 || !args[0]->IsString() || !args[1]->IsObject() ||
-      !args[2]->IsObject()) {
-    v8::ThrowException(v8::Exception::Error(
-        v8::String::New("Internal error, wrong parameters.")));
-    return;
-  }
-
-  v8::Isolate* isolate = args.GetIsolate();
-  v8::Local<v8::ObjectTemplate> break_iterator_template =
-      Utils::GetTemplate2(isolate);
-
-  // Create an empty object wrapper.
- v8::Local<v8::Object> local_object = break_iterator_template->NewInstance();
-  // But the handle shouldn't be empty.
- // That can happen if there was a stack overflow when creating the object.
-  if (local_object.IsEmpty()) {
-    args.GetReturnValue().Set(local_object);
-    return;
-  }
-
-  // Set break iterator as internal field of the resulting JS object.
-  icu::BreakIterator* break_iterator = InitializeBreakIterator(
-      args[0]->ToString(), args[1]->ToObject(), args[2]->ToObject());
-
-  if (!break_iterator) {
-    v8::ThrowException(v8::Exception::Error(v8::String::New(
-        "Internal error. Couldn't create ICU break iterator.")));
-    return;
-  } else {
-    local_object->SetAlignedPointerInInternalField(0, break_iterator);
-    // Make sure that the pointer to adopted text is NULL.
-    local_object->SetAlignedPointerInInternalField(1, NULL);
-
-    v8::TryCatch try_catch;
-    local_object->Set(v8::String::New("breakIterator"),
-                      v8::String::New("valid"));
-    if (try_catch.HasCaught()) {
-      v8::ThrowException(v8::Exception::Error(
-          v8::String::New("Internal error, couldn't set property.")));
-      return;
-    }
-  }
-
-  v8::Persistent<v8::Object> wrapper(isolate, local_object);
-  // Make object handle weak so we can delete iterator once GC kicks in.
-  wrapper.MakeWeak<void>(NULL, &DeleteBreakIterator);
-  args.GetReturnValue().Set(wrapper);
-  wrapper.ClearAndLeak();
-}
-
-static icu::BreakIterator* InitializeBreakIterator(
-    v8::Handle<v8::String> locale,
-    v8::Handle<v8::Object> options,
-    v8::Handle<v8::Object> resolved) {
-  // Convert BCP47 into ICU locale format.
-  UErrorCode status = U_ZERO_ERROR;
-  icu::Locale icu_locale;
-  char icu_result[ULOC_FULLNAME_CAPACITY];
-  int icu_length = 0;
-  v8::String::AsciiValue bcp47_locale(locale);
-  if (bcp47_locale.length() != 0) {
-    uloc_forLanguageTag(*bcp47_locale, icu_result, ULOC_FULLNAME_CAPACITY,
-                        &icu_length, &status);
-    if (U_FAILURE(status) || icu_length == 0) {
-      return NULL;
-    }
-    icu_locale = icu::Locale(icu_result);
-  }
-
-  icu::BreakIterator* break_iterator =
-    CreateICUBreakIterator(icu_locale, options);
-  if (!break_iterator) {
-    // Remove extensions and try again.
-    icu::Locale no_extension_locale(icu_locale.getBaseName());
-    break_iterator = CreateICUBreakIterator(no_extension_locale, options);
-
-    // Set resolved settings (locale).
-    SetResolvedSettings(no_extension_locale, break_iterator, resolved);
-  } else {
-    SetResolvedSettings(icu_locale, break_iterator, resolved);
-  }
-
-  return break_iterator;
-}
-
-static icu::BreakIterator* CreateICUBreakIterator(
-    const icu::Locale& icu_locale, v8::Handle<v8::Object> options) {
-  UErrorCode status = U_ZERO_ERROR;
-  icu::BreakIterator* break_iterator = NULL;
-  icu::UnicodeString type;
-  if (!Utils::ExtractStringSetting(options, "type", &type)) {
-    // Type had to be in the options. This would be an internal error.
-    return NULL;
-  }
-
-  if (type == UNICODE_STRING_SIMPLE("character")) {
-    break_iterator =
-      icu::BreakIterator::createCharacterInstance(icu_locale, status);
-  } else if (type == UNICODE_STRING_SIMPLE("sentence")) {
-    break_iterator =
-      icu::BreakIterator::createSentenceInstance(icu_locale, status);
-  } else if (type == UNICODE_STRING_SIMPLE("line")) {
-    break_iterator =
-      icu::BreakIterator::createLineInstance(icu_locale, status);
-  } else {
-    // Defualt is word iterator.
-    break_iterator =
-      icu::BreakIterator::createWordInstance(icu_locale, status);
-  }
-
-  if (U_FAILURE(status)) {
-    delete break_iterator;
-    return NULL;
-  }
-
-  return break_iterator;
-}
-
-static void SetResolvedSettings(const icu::Locale& icu_locale,
-                                icu::BreakIterator* date_format,
-                                v8::Handle<v8::Object> resolved) {
-  UErrorCode status = U_ZERO_ERROR;
-
-  // Set the locale
-  char result[ULOC_FULLNAME_CAPACITY];
-  status = U_ZERO_ERROR;
-  uloc_toLanguageTag(
- icu_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status);
-  if (U_SUCCESS(status)) {
-    resolved->Set(v8::String::New("locale"), v8::String::New(result));
-  } else {
-    // This would never happen, since we got the locale from ICU.
-    resolved->Set(v8::String::New("locale"), v8::String::New("und"));
-  }
-}
-
-}  // namespace v8_i18n
=======================================
--- /branches/bleeding_edge/src/extensions/i18n/break-iterator.h Wed Jul 3 11:22:29 2013 UTC
+++ /dev/null
@@ -1,85 +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_BREAK_ITERATOR_H_
-#define V8_EXTENSIONS_I18N_BREAK_ITERATOR_H_
-
-#include "unicode/uversion.h"
-#include "v8.h"
-
-namespace U_ICU_NAMESPACE {
-class BreakIterator;
-class UnicodeString;
-}
-
-namespace v8_i18n {
-
-class BreakIterator {
- public:
-  static void JSCreateBreakIterator(
-      const v8::FunctionCallbackInfo<v8::Value>& args);
-
-  // Helper methods for various bindings.
-
-  // Unpacks iterator object from corresponding JavaScript object.
- static icu::BreakIterator* UnpackBreakIterator(v8::Handle<v8::Object> obj);
-
- // Release memory we allocated for the BreakIterator once the JS object that
-  // holds the pointer gets garbage collected.
-  static void DeleteBreakIterator(v8::Isolate* isolate,
-                                  v8::Persistent<v8::Object>* object,
-                                  void* param);
-
-  // Assigns new text to the iterator.
-  static void JSInternalBreakIteratorAdoptText(
-      const v8::FunctionCallbackInfo<v8::Value>& args);
-
- // Moves iterator to the beginning of the string and returns new position.
-  static void JSInternalBreakIteratorFirst(
-      const v8::FunctionCallbackInfo<v8::Value>& args);
-
-  // Moves iterator to the next position and returns it.
-  static void JSInternalBreakIteratorNext(
-      const v8::FunctionCallbackInfo<v8::Value>& args);
-
-  // Returns current iterator's current position.
-  static void JSInternalBreakIteratorCurrent(
-      const v8::FunctionCallbackInfo<v8::Value>& args);
-
-  // Returns type of the item from current position.
- // This call is only valid for word break iterators. Others just return 0.
-  static void JSInternalBreakIteratorBreakType(
-      const v8::FunctionCallbackInfo<v8::Value>& args);
-
- private:
-  BreakIterator() {}
-};
-
-}  // namespace v8_i18n
-
-#endif  // V8_EXTENSIONS_I18N_BREAK_ITERATOR_H_
=======================================
--- /branches/bleeding_edge/src/extensions/i18n/i18n-utils.cc Mon Aug 5 09:46:23 2013 UTC
+++ /dev/null
@@ -1,177 +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 "i18n-utils.h"
-
-#include <string.h>
-
-#include "unicode/unistr.h"
-
-namespace v8_i18n {
-
-// static
-void Utils::StrNCopy(char* dest, int length, const char* src) {
-  if (!dest || !src) return;
-
-  strncpy(dest, src, length);
-  dest[length - 1] = '\0';
-}
-
-
-// static
-bool Utils::V8StringToUnicodeString(const v8::Handle<v8::Value>& input,
-                                    icu::UnicodeString* output) {
-  v8::String::Utf8Value utf8_value(input);
-
-  if (*utf8_value == NULL) return false;
-
-  output->setTo(icu::UnicodeString::fromUTF8(*utf8_value));
-
-  return true;
-}
-
-
-// static
-bool Utils::ExtractStringSetting(const v8::Handle<v8::Object>& settings,
-                                 const char* setting,
-                                 icu::UnicodeString* result) {
-  if (!setting || !result) return false;
-
-  v8::HandleScope handle_scope;
-  v8::TryCatch try_catch;
-  v8::Handle<v8::Value> value = settings->Get(v8::String::New(setting));
-  if (try_catch.HasCaught()) {
-    return false;
-  }
-  // No need to check if |value| is empty because it's taken care of
-  // by TryCatch above.
-  if (!value->IsUndefined() && !value->IsNull() && value->IsString()) {
-    return V8StringToUnicodeString(value, result);
-  }
-  return false;
-}
-
-
-// static
-bool Utils::ExtractIntegerSetting(const v8::Handle<v8::Object>& settings,
-                                  const char* setting,
-                                  int32_t* result) {
-  if (!setting || !result) return false;
-
-  v8::HandleScope handle_scope;
-  v8::TryCatch try_catch;
-  v8::Handle<v8::Value> value = settings->Get(v8::String::New(setting));
-  if (try_catch.HasCaught()) {
-    return false;
-  }
-  // No need to check if |value| is empty because it's taken care of
-  // by TryCatch above.
-  if (!value->IsUndefined() && !value->IsNull() && value->IsNumber()) {
-    *result = static_cast<int32_t>(value->Int32Value());
-    return true;
-  }
-  return false;
-}
-
-
-// static
-bool Utils::ExtractBooleanSetting(const v8::Handle<v8::Object>& settings,
-                                  const char* setting,
-                                  bool* result) {
-  if (!setting || !result) return false;
-
-  v8::HandleScope handle_scope;
-  v8::TryCatch try_catch;
-  v8::Handle<v8::Value> value = settings->Get(v8::String::New(setting));
-  if (try_catch.HasCaught()) {
-    return false;
-  }
-  // No need to check if |value| is empty because it's taken care of
-  // by TryCatch above.
-  if (!value->IsUndefined() && !value->IsNull() && value->IsBoolean()) {
-    *result = static_cast<bool>(value->BooleanValue());
-    return true;
-  }
-  return false;
-}
-
-
-// static
-void Utils::AsciiToUChar(const char* source,
-                         int32_t source_length,
-                         UChar* target,
-                         int32_t target_length) {
-  int32_t length =
-      source_length < target_length ? source_length : target_length;
-
-  if (length <= 0) {
-    return;
-  }
-
-  for (int32_t i = 0; i < length - 1; ++i) {
-    target[i] = static_cast<UChar>(source[i]);
-  }
-
-  target[length - 1] = 0x0u;
-}
-
-
-static v8::Local<v8::ObjectTemplate> ToLocal(i::Handle<i::Object> handle) {
- return v8::Utils::ToLocal(i::Handle<i::ObjectTemplateInfo>::cast(handle));
-}
-
-
-template<int internal_fields, i::EternalHandles::SingletonHandle field>
-static v8::Local<v8::ObjectTemplate> GetEternal(v8::Isolate* external) {
-  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external);
-  if (isolate->eternal_handles()->Exists(field)) {
-    return ToLocal(isolate->eternal_handles()->GetSingleton(field));
-  }
-  v8::Local<v8::ObjectTemplate> raw_template(v8::ObjectTemplate::New());
-  raw_template->SetInternalFieldCount(internal_fields);
-  return ToLocal(
-      isolate->eternal_handles()->CreateSingleton(
-        isolate,
-        *v8::Utils::OpenHandle(*raw_template),
-        field));
-}
-
-
-// static
-v8::Local<v8::ObjectTemplate> Utils::GetTemplate(v8::Isolate* isolate) {
-  return GetEternal<1, i::EternalHandles::I18N_TEMPLATE_ONE>(isolate);
-}
-
-
-// static
-v8::Local<v8::ObjectTemplate> Utils::GetTemplate2(v8::Isolate* isolate) {
-  return GetEternal<2, i::EternalHandles::I18N_TEMPLATE_TWO>(isolate);
-}
-
-
-}  // namespace v8_i18n
=======================================
--- /branches/bleeding_edge/src/extensions/i18n/i18n-utils.h Wed Jul 3 11:22:29 2013 UTC
+++ /dev/null
@@ -1,91 +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_UTILS_H_
-#define V8_EXTENSIONS_I18N_SRC_UTILS_H_
-
-#include "unicode/uversion.h"
-#include "v8.h"
-
-namespace U_ICU_NAMESPACE {
-class UnicodeString;
-}
-
-namespace v8_i18n {
-
-class Utils {
- public:
-  // Safe string copy. Null terminates the destination. Copies at most
-  // (length - 1) bytes.
- // We can't use snprintf since it's not supported on all relevant platforms.
-  // We can't use OS::SNPrintF, it's only for internal code.
-  static void StrNCopy(char* dest, int length, const char* src);
-
-  // Converts v8::String into UnicodeString. Returns false if input
-  // can't be converted into utf8.
-  static bool V8StringToUnicodeString(const v8::Handle<v8::Value>& input,
-                                      icu::UnicodeString* output);
-
-  // Extract a String setting named in |settings| and set it to |result|.
-  // Return true if it's specified. Otherwise, return false.
-  static bool ExtractStringSetting(const v8::Handle<v8::Object>& settings,
-                                   const char* setting,
-                                   icu::UnicodeString* result);
-
-  // Extract a Integer setting named in |settings| and set it to |result|.
-  // Return true if it's specified. Otherwise, return false.
-  static bool ExtractIntegerSetting(const v8::Handle<v8::Object>& settings,
-                                    const char* setting,
-                                    int32_t* result);
-
-  // Extract a Boolean setting named in |settings| and set it to |result|.
-  // Return true if it's specified. Otherwise, return false.
-  static bool ExtractBooleanSetting(const v8::Handle<v8::Object>& settings,
-                                    const char* setting,
-                                    bool* result);
-
-  // Converts ASCII array into UChar array.
-  // Target is always \0 terminated.
-  static void AsciiToUChar(const char* source,
-                           int32_t source_length,
-                           UChar* target,
-                           int32_t target_length);
-
-  // Creates an ObjectTemplate with one internal field.
-  static v8::Local<v8::ObjectTemplate> GetTemplate(v8::Isolate* isolate);
-
-  // Creates an ObjectTemplate with two internal fields.
-  static v8::Local<v8::ObjectTemplate> GetTemplate2(v8::Isolate* isolate);
-
- private:
-  Utils() {}
-};
-
-}  // namespace v8_i18n
-
-#endif  // V8_EXTENSIONS_I18N_UTILS_H_
=======================================
--- /branches/bleeding_edge/src/extensions/i18n/break-iterator.js Wed Jul 3 15:30:27 2013 UTC +++ /branches/bleeding_edge/src/extensions/i18n/break-iterator.js Tue Aug 20 08:46:36 2013 UTC
@@ -35,8 +35,6 @@
  * Useful for subclassing.
  */
 function initializeBreakIterator(iterator, locales, options) {
-  native function NativeJSCreateBreakIterator();
-
   if (iterator.hasOwnProperty('__initializedIntlObject')) {
     throw new TypeError('Trying to re-initialize v8BreakIterator object.');
   }
@@ -59,9 +57,9 @@
     locale: {writable: true}
   });

-  var internalIterator = NativeJSCreateBreakIterator(locale.locale,
-                                                     internalOptions,
-                                                     resolved);
+  var internalIterator = %CreateBreakIterator(locale.locale,
+                                              internalOptions,
+                                              resolved);

   Object.defineProperty(iterator, 'iterator', {value: internalIterator});
   Object.defineProperty(iterator, 'resolved', {value: resolved});
@@ -149,8 +147,7 @@
  * gets discarded.
  */
 function adoptText(iterator, text) {
-  native function NativeJSBreakIteratorAdoptText();
-  NativeJSBreakIteratorAdoptText(iterator.iterator, String(text));
+  %BreakIteratorAdoptText(iterator.iterator, String(text));
 }


@@ -158,8 +155,7 @@
* Returns index of the first break in the string and moves current pointer.
  */
 function first(iterator) {
-  native function NativeJSBreakIteratorFirst();
-  return NativeJSBreakIteratorFirst(iterator.iterator);
+  return %BreakIteratorFirst(iterator.iterator);
 }


@@ -167,8 +163,7 @@
  * Returns the index of the next break and moves the pointer.
  */
 function next(iterator) {
-  native function NativeJSBreakIteratorNext();
-  return NativeJSBreakIteratorNext(iterator.iterator);
+  return %BreakIteratorNext(iterator.iterator);
 }


@@ -176,8 +171,7 @@
  * Returns index of the current break.
  */
 function current(iterator) {
-  native function NativeJSBreakIteratorCurrent();
-  return NativeJSBreakIteratorCurrent(iterator.iterator);
+  return %BreakIteratorCurrent(iterator.iterator);
 }


@@ -185,8 +179,7 @@
  * Returns type of the current break.
  */
 function breakType(iterator) {
-  native function NativeJSBreakIteratorBreakType();
-  return NativeJSBreakIteratorBreakType(iterator.iterator);
+  return %BreakIteratorBreakType(iterator.iterator);
 }


=======================================
--- /branches/bleeding_edge/src/extensions/i18n/i18n-extension.cc Fri Aug 9 09:51:09 2013 UTC +++ /branches/bleeding_edge/src/extensions/i18n/i18n-extension.cc Tue Aug 20 08:46:36 2013 UTC
@@ -28,7 +28,6 @@

 #include "i18n-extension.h"

-#include "break-iterator.h"
 #include "natives.h"

 using v8::internal::I18NNatives;
@@ -42,31 +41,6 @@
                     0,
                     0,
                     I18NNatives::GetScriptsSource().length()) {}
-
-v8::Handle<v8::FunctionTemplate> Extension::GetNativeFunction(
-    v8::Handle<v8::String> name) {
-  // Break iterator.
-  if (name->Equals(v8::String::New("NativeJSCreateBreakIterator"))) {
-    return v8::FunctionTemplate::New(BreakIterator::JSCreateBreakIterator);
- } else if (name->Equals(v8::String::New("NativeJSBreakIteratorAdoptText"))) {
-    return v8::FunctionTemplate::New(
-        BreakIterator::JSInternalBreakIteratorAdoptText);
-  } else if (name->Equals(v8::String::New("NativeJSBreakIteratorFirst"))) {
-    return v8::FunctionTemplate::New(
-        BreakIterator::JSInternalBreakIteratorFirst);
-  } else if (name->Equals(v8::String::New("NativeJSBreakIteratorNext"))) {
-    return v8::FunctionTemplate::New(
-        BreakIterator::JSInternalBreakIteratorNext);
- } else if (name->Equals(v8::String::New("NativeJSBreakIteratorCurrent"))) {
-    return v8::FunctionTemplate::New(
-        BreakIterator::JSInternalBreakIteratorCurrent);
- } else if (name->Equals(v8::String::New("NativeJSBreakIteratorBreakType"))) {
-    return v8::FunctionTemplate::New(
-        BreakIterator::JSInternalBreakIteratorBreakType);
-  }
-
-  return v8::Handle<v8::FunctionTemplate>();
-}


 void Extension::Register() {
=======================================
--- /branches/bleeding_edge/src/extensions/i18n/i18n-extension.h Wed Jul 3 11:22:29 2013 UTC +++ /branches/bleeding_edge/src/extensions/i18n/i18n-extension.h Tue Aug 20 08:46:36 2013 UTC
@@ -37,9 +37,6 @@
  public:
   Extension();

-  virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
-      v8::Handle<v8::String> name);
-
   static void Register();

  private:
=======================================
--- /branches/bleeding_edge/src/i18n.cc Tue Aug 20 08:07:52 2013 UTC
+++ /branches/bleeding_edge/src/i18n.cc Tue Aug 20 08:46:36 2013 UTC
@@ -28,6 +28,7 @@

 #include "i18n.h"

+#include "unicode/brkiter.h"
 #include "unicode/calendar.h"
 #include "unicode/coll.h"
 #include "unicode/curramt.h"
@@ -38,6 +39,7 @@
 #include "unicode/locid.h"
 #include "unicode/numfmt.h"
 #include "unicode/numsys.h"
+#include "unicode/rbbi.h"
 #include "unicode/smpdtfmt.h"
 #include "unicode/timezone.h"
 #include "unicode/uchar.h"
@@ -731,6 +733,69 @@
   }
 }

+
+icu::BreakIterator* CreateICUBreakIterator(
+    Isolate* isolate,
+    const icu::Locale& icu_locale,
+    Handle<JSObject> options) {
+  UErrorCode status = U_ZERO_ERROR;
+  icu::BreakIterator* break_iterator = NULL;
+  icu::UnicodeString type;
+  if (!ExtractStringSetting(isolate, options, "type", &type)) return NULL;
+
+  if (type == UNICODE_STRING_SIMPLE("character")) {
+    break_iterator =
+      icu::BreakIterator::createCharacterInstance(icu_locale, status);
+  } else if (type == UNICODE_STRING_SIMPLE("sentence")) {
+    break_iterator =
+      icu::BreakIterator::createSentenceInstance(icu_locale, status);
+  } else if (type == UNICODE_STRING_SIMPLE("line")) {
+    break_iterator =
+      icu::BreakIterator::createLineInstance(icu_locale, status);
+  } else {
+    // Defualt is word iterator.
+    break_iterator =
+      icu::BreakIterator::createWordInstance(icu_locale, status);
+  }
+
+  if (U_FAILURE(status)) {
+    delete break_iterator;
+    return NULL;
+  }
+
+  return break_iterator;
+}
+
+
+void SetResolvedBreakIteratorSettings(Isolate* isolate,
+                                      const icu::Locale& icu_locale,
+                                      icu::BreakIterator* break_iterator,
+                                      Handle<JSObject> resolved) {
+  UErrorCode status = U_ZERO_ERROR;
+
+  // Set the locale
+  char result[ULOC_FULLNAME_CAPACITY];
+  status = U_ZERO_ERROR;
+  uloc_toLanguageTag(
+ icu_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status);
+  if (U_SUCCESS(status)) {
+    JSObject::SetProperty(
+        resolved,
+        isolate->factory()->NewStringFromAscii(CStrVector("locale")),
+        isolate->factory()->NewStringFromAscii(CStrVector(result)),
+        NONE,
+        kNonStrictMode);
+  } else {
+    // This would never happen, since we got the locale from ICU.
+    JSObject::SetProperty(
+        resolved,
+        isolate->factory()->NewStringFromAscii(CStrVector("locale")),
+        isolate->factory()->NewStringFromAscii(CStrVector("und")),
+        NONE,
+        kNonStrictMode);
+  }
+}
+
 }  // namespace


@@ -934,5 +999,72 @@
   // Then dispose of the persistent handle to JS object.
   object->Dispose(isolate);
 }
+
+
+icu::BreakIterator* BreakIterator::InitializeBreakIterator(
+    Isolate* isolate,
+    Handle<String> locale,
+    Handle<JSObject> options,
+    Handle<JSObject> resolved) {
+  // Convert BCP47 into ICU locale format.
+  UErrorCode status = U_ZERO_ERROR;
+  icu::Locale icu_locale;
+  char icu_result[ULOC_FULLNAME_CAPACITY];
+  int icu_length = 0;
+  v8::String::Utf8Value bcp47_locale(v8::Utils::ToLocal(locale));
+  if (bcp47_locale.length() != 0) {
+    uloc_forLanguageTag(*bcp47_locale, icu_result, ULOC_FULLNAME_CAPACITY,
+                        &icu_length, &status);
+    if (U_FAILURE(status) || icu_length == 0) {
+      return NULL;
+    }
+    icu_locale = icu::Locale(icu_result);
+  }
+
+  icu::BreakIterator* break_iterator = CreateICUBreakIterator(
+      isolate, icu_locale, options);
+  if (!break_iterator) {
+    // Remove extensions and try again.
+    icu::Locale no_extension_locale(icu_locale.getBaseName());
+    break_iterator = CreateICUBreakIterator(
+        isolate, no_extension_locale, options);
+
+    // Set resolved settings (locale).
+    SetResolvedBreakIteratorSettings(
+        isolate, no_extension_locale, break_iterator, resolved);
+  } else {
+    SetResolvedBreakIteratorSettings(
+        isolate, icu_locale, break_iterator, resolved);
+  }
+
+  return break_iterator;
+}
+
+
+icu::BreakIterator* BreakIterator::UnpackBreakIterator(Isolate* isolate,
+ Handle<JSObject> obj) {
+  Handle<String> key =
+      isolate->factory()->NewStringFromAscii(CStrVector("breakIterator"));
+  if (obj->HasLocalProperty(*key)) {
+    return reinterpret_cast<icu::BreakIterator*>(obj->GetInternalField(0));
+  }
+
+  return NULL;
+}
+
+
+void BreakIterator::DeleteBreakIterator(v8::Isolate* isolate,
+                                        Persistent<v8::Value>* object,
+                                        void* param) {
+  // First delete the hidden C++ object.
+  delete reinterpret_cast<icu::BreakIterator*>(Handle<JSObject>::cast(
+      v8::Utils::OpenPersistent(object))->GetInternalField(0));
+
+  delete reinterpret_cast<icu::UnicodeString*>(Handle<JSObject>::cast(
+      v8::Utils::OpenPersistent(object))->GetInternalField(1));
+
+  // Then dispose of the persistent handle to JS object.
+  object->Dispose(isolate);
+}

 } }  // namespace v8::internal
=======================================
--- /branches/bleeding_edge/src/i18n.h  Tue Aug 20 08:07:52 2013 UTC
+++ /branches/bleeding_edge/src/i18n.h  Tue Aug 20 08:46:36 2013 UTC
@@ -33,6 +33,7 @@
 #include "v8.h"

 namespace U_ICU_NAMESPACE {
+class BreakIterator;
 class Collator;
 class DecimalFormat;
 class SimpleDateFormat;
@@ -124,6 +125,30 @@
   Collator();
 };

+class BreakIterator {
+ public:
+ // Create a BreakIterator for the specificied locale and options. Returns the
+  // resolved settings for the locale / options.
+  static icu::BreakIterator* InitializeBreakIterator(
+      Isolate* isolate,
+      Handle<String> locale,
+      Handle<JSObject> options,
+      Handle<JSObject> resolved);
+
+  // Unpacks break iterator object from corresponding JavaScript object.
+  static icu::BreakIterator* UnpackBreakIterator(Isolate* isolate,
+                                                 Handle<JSObject> obj);
+
+ // Release memory we allocated for the BreakIterator once the JS object that
+  // holds the pointer gets garbage collected.
+  static void DeleteBreakIterator(v8::Isolate* isolate,
+                                  Persistent<v8::Value>* object,
+                                  void* param);
+
+ private:
+  BreakIterator();
+};
+
 } }  // namespace v8::internal

 #endif  // V8_I18N_H_
=======================================
--- /branches/bleeding_edge/src/runtime.cc      Tue Aug 20 08:17:43 2013 UTC
+++ /branches/bleeding_edge/src/runtime.cc      Tue Aug 20 08:46:36 2013 UTC
@@ -80,6 +80,7 @@
 #include "unicode/locid.h"
 #include "unicode/numfmt.h"
 #include "unicode/numsys.h"
+#include "unicode/rbbi.h"
 #include "unicode/smpdtfmt.h"
 #include "unicode/timezone.h"
 #include "unicode/uchar.h"
@@ -13879,6 +13880,158 @@

   return *isolate->factory()->NewNumberFromInt(result);
 }
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateBreakIterator) {
+  HandleScope scope(isolate);
+
+  ASSERT(args.length() == 3);
+
+  CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
+
+  Handle<ObjectTemplateInfo> break_iterator_template =
+      I18N::GetTemplate2(isolate);
+
+  // Create an empty object wrapper.
+  bool has_pending_exception = false;
+  Handle<JSObject> local_object = Execution::InstantiateObject(
+      break_iterator_template, &has_pending_exception);
+  if (has_pending_exception) {
+    ASSERT(isolate->has_pending_exception());
+    return Failure::Exception();
+  }
+
+  // Set break iterator as internal field of the resulting JS object.
+ icu::BreakIterator* break_iterator = BreakIterator::InitializeBreakIterator(
+      isolate, locale, options, resolved);
+
+  if (!break_iterator) return isolate->ThrowIllegalOperation();
+
+ local_object->SetInternalField(0, reinterpret_cast<Smi*>(break_iterator));
+  // Make sure that the pointer to adopted text is NULL.
+  local_object->SetInternalField(1, reinterpret_cast<Smi*>(NULL));
+
+  RETURN_IF_EMPTY_HANDLE(isolate,
+      JSObject::SetLocalPropertyIgnoreAttributes(
+          local_object,
+ isolate->factory()->NewStringFromAscii(CStrVector("breakIterator")),
+          isolate->factory()->NewStringFromAscii(CStrVector("valid")),
+          NONE));
+
+ // Make object handle weak so we can delete the break iterator once GC kicks
+  // in.
+ Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
+  GlobalHandles::MakeWeak(reinterpret_cast<Object**>(wrapper.location()),
+                          NULL,
+                          BreakIterator::DeleteBreakIterator);
+  return *local_object;
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_BreakIteratorAdoptText) {
+  HandleScope scope(isolate);
+
+  ASSERT(args.length() == 2);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, text, 1);
+
+  icu::BreakIterator* break_iterator =
+      BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
+  if (!break_iterator) return isolate->ThrowIllegalOperation();
+
+  icu::UnicodeString* u_text = reinterpret_cast<icu::UnicodeString*>(
+      break_iterator_holder->GetInternalField(1));
+  delete u_text;
+
+  v8::String::Value text_value(v8::Utils::ToLocal(text));
+  u_text = new icu::UnicodeString(
+      reinterpret_cast<const UChar*>(*text_value), text_value.length());
+ break_iterator_holder->SetInternalField(1, reinterpret_cast<Smi*>(u_text));
+
+  break_iterator->setText(*u_text);
+
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_BreakIteratorFirst) {
+  HandleScope scope(isolate);
+
+  ASSERT(args.length() == 1);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
+
+  icu::BreakIterator* break_iterator =
+      BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
+  if (!break_iterator) return isolate->ThrowIllegalOperation();
+
+  return *isolate->factory()->NewNumberFromInt(break_iterator->first());
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_BreakIteratorNext) {
+  HandleScope scope(isolate);
+
+  ASSERT(args.length() == 1);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
+
+  icu::BreakIterator* break_iterator =
+      BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
+  if (!break_iterator) return isolate->ThrowIllegalOperation();
+
+  return *isolate->factory()->NewNumberFromInt(break_iterator->next());
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_BreakIteratorCurrent) {
+  HandleScope scope(isolate);
+
+  ASSERT(args.length() == 1);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
+
+  icu::BreakIterator* break_iterator =
+      BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
+  if (!break_iterator) return isolate->ThrowIllegalOperation();
+
+  return *isolate->factory()->NewNumberFromInt(break_iterator->current());
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_BreakIteratorBreakType) {
+  HandleScope scope(isolate);
+
+  ASSERT(args.length() == 1);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
+
+  icu::BreakIterator* break_iterator =
+      BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
+  if (!break_iterator) return isolate->ThrowIllegalOperation();
+
+  // TODO(cira): Remove cast once ICU fixes base BreakIterator class.
+  icu::RuleBasedBreakIterator* rule_based_iterator =
+      static_cast<icu::RuleBasedBreakIterator*>(break_iterator);
+  int32_t status = rule_based_iterator->getRuleStatus();
+  // Keep return values in sync with JavaScript BreakType enum.
+  if (status >= UBRK_WORD_NONE && status < UBRK_WORD_NONE_LIMIT) {
+    return *isolate->factory()->NewStringFromAscii(CStrVector("none"));
+ } else if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) {
+    return *isolate->factory()->NewStringFromAscii(CStrVector("number"));
+ } else if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) {
+    return *isolate->factory()->NewStringFromAscii(CStrVector("letter"));
+  } else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) {
+    return *isolate->factory()->NewStringFromAscii(CStrVector("kana"));
+  } else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) {
+    return *isolate->factory()->NewStringFromAscii(CStrVector("ideo"));
+  } else {
+    return *isolate->factory()->NewStringFromAscii(CStrVector("unknown"));
+  }
+}
 #endif  // V8_I18N_SUPPORT


=======================================
--- /branches/bleeding_edge/src/runtime.h       Fri Aug 16 15:10:07 2013 UTC
+++ /branches/bleeding_edge/src/runtime.h       Tue Aug 20 08:46:36 2013 UTC
@@ -558,6 +558,14 @@
   /* Collator. */ \
   F(CreateCollator, 3, 1) \
   F(InternalCompare, 3, 1) \
+  \
+  /* Break iterator. */ \
+  F(CreateBreakIterator, 3, 1) \
+  F(BreakIteratorAdoptText, 2, 1) \
+  F(BreakIteratorFirst, 1, 1) \
+  F(BreakIteratorNext, 1, 1) \
+  F(BreakIteratorCurrent, 1, 1) \
+  F(BreakIteratorBreakType, 1, 1) \

 #else
 #define RUNTIME_FUNCTION_LIST_I18N_SUPPORT(F)
=======================================
--- /branches/bleeding_edge/tools/gyp/v8.gyp    Tue Aug 20 08:29:21 2013 UTC
+++ /branches/bleeding_edge/tools/gyp/v8.gyp    Tue Aug 20 08:46:36 2013 UTC
@@ -380,6 +380,8 @@
         '../../src/hydrogen-uint32-analysis.h',
         '../../src/hydrogen-osr.cc',
         '../../src/hydrogen-osr.h',
+        '../../src/i18n.cc',
+        '../../src/i18n.h',
         '../../src/icu_util.cc',
         '../../src/icu_util.h',
         '../../src/ic-inl.h',
@@ -874,19 +876,18 @@
         }],
         ['v8_enable_i18n_support==1', {
           'sources': [
-            '../../src/i18n.cc',
-            '../../src/i18n.h',
-            '../../src/extensions/i18n/break-iterator.cc',
-            '../../src/extensions/i18n/break-iterator.h',
             '../../src/extensions/i18n/i18n-extension.cc',
             '../../src/extensions/i18n/i18n-extension.h',
-            '../../src/extensions/i18n/i18n-utils.cc',
-            '../../src/extensions/i18n/i18n-utils.h',
           ],
           'dependencies': [
             '<(DEPTH)/third_party/icu/icu.gyp:icui18n',
             '<(DEPTH)/third_party/icu/icu.gyp:icuuc',
           ]
+        }, {  # v8_enable_i18n_support==0
+          'sources!': [
+            '../../src/i18n.cc',
+            '../../src/i18n.h',
+          ],
         }],
         ['OS=="win" and v8_enable_i18n_support==1', {
           'dependencies': [

--
--
v8-dev mailing list
v8-dev@googlegroups.com
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 v8-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to