diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index e8eb3283aadea686aee5a170c8a68530256ae1e8..d1ae9d78d2efce4952bba7b52f12aa09ee9da439 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -3060,6 +3060,18 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, factory->empty_string(), 0); native_context()->set_break_iterator_internal_current_shared_fun(*info); } + + SimpleInstallGetter(isolate_, prototype, + factory->InternalizeUtf8String("breakType"), + Builtins::kBreakIteratorPrototypeBreakType, false); + + { + Handle<SharedFunctionInfo> info = SimpleCreateBuiltinSharedFunctionInfo( + isolate_, Builtins::kBreakIteratorInternalBreakType, + factory->empty_string(), 0); + native_context()->set_break_iterator_internal_break_type_shared_fun( + *info); + } } { diff --git a/src/builtins/builtins-definitions.h b/src/builtins/builtins-definitions.h index 75464801058a4e758a0ac3be1019eb53228a61f0..e9e46c055138b43242ea1f7879cd8937f61a132d 100644 --- a/src/builtins/builtins-definitions.h +++ b/src/builtins/builtins-definitions.h @@ -1411,7 +1411,9 @@ namespace internal { CPP(BreakIteratorInternalNext) \ CPP(BreakIteratorPrototypeNext) \ CPP(BreakIteratorInternalCurrent) \ - CPP(BreakIteratorPrototypeCurrent) + CPP(BreakIteratorPrototypeCurrent) \ + CPP(BreakIteratorInternalBreakType) \ + CPP(BreakIteratorPrototypeBreakType) #else #define BUILTIN_LIST_INTL(CPP, TFJ, TFS) \ /* no-op fallback version */ \ diff --git a/src/builtins/builtins-intl.cc b/src/builtins/builtins-intl.cc index f394f3e22e38689c2e2cc68b49797974c852efc4..af27fd1444cdb1231bbef048ad304677cce2b919 100644 --- a/src/builtins/builtins-intl.cc +++ b/src/builtins/builtins-intl.cc @@ -1576,5 +1576,82 @@ BUILTIN(BreakIteratorInternalCurrent) { return *isolate->factory()->NewNumberFromInt(break_iterator->current()); } +BUILTIN(BreakIteratorPrototypeBreakType) { + const char* const method = "get Intl.v8BreakIterator.prototype.breakType"; + HandleScope scope(isolate); + + CHECK_RECEIVER(JSObject, break_iterator_holder, method); + if (!Intl::IsObjectOfType(isolate, break_iterator_holder, + Intl::Type::kBreakIterator)) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, + NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, + isolate->factory()->NewStringFromAsciiChecked(method), + break_iterator_holder)); + } + + Handle<Object> bound_break_type = + Handle<Object>(break_iterator_holder->GetEmbedderField( + V8BreakIterator::kBoundBreakTypeIndex), + isolate); + + if (!bound_break_type->IsUndefined(isolate)) { + DCHECK(bound_break_type->IsJSFunction()); + return *bound_break_type; + } + + Handle<NativeContext> native_context(isolate->context()->native_context(), + isolate); + Handle<Context> context = isolate->factory()->NewBuiltinContext( + native_context, static_cast<int>(V8BreakIterator::ContextSlot::kLength)); + + context->set(static_cast<int>(V8BreakIterator::ContextSlot::kV8BreakIterator), + *break_iterator_holder); + + Handle<SharedFunctionInfo> info = Handle<SharedFunctionInfo>( + native_context->break_iterator_internal_break_type_shared_fun(), isolate); + Handle<Map> map = isolate->strict_function_without_prototype_map(); + + Handle<JSFunction> new_bound_break_type_function = + isolate->factory()->NewFunctionFromSharedFunctionInfo(map, info, context); + break_iterator_holder->SetEmbedderField(V8BreakIterator::kBoundBreakTypeIndex, + *new_bound_break_type_function); + + return *new_bound_break_type_function; +} + +BUILTIN(BreakIteratorInternalBreakType) { + HandleScope scope(isolate); + Handle<Context> context = Handle<Context>(isolate->context(), isolate); + + Handle<JSObject> break_iterator_holder = Handle<JSObject>( + JSObject::cast(context->get( + static_cast<int>(V8BreakIterator::ContextSlot::kV8BreakIterator))), + isolate); + + DCHECK(Intl::IsObjectOfType(isolate, break_iterator_holder, + Intl::Type::kBreakIterator)); + + icu::BreakIterator* break_iterator = + V8BreakIterator::UnpackBreakIterator(break_iterator_holder); + CHECK_NOT_NULL(break_iterator); + + int32_t status = break_iterator->getRuleStatus(); + // Keep return values in sync with JavaScript BreakType enum. + if (status >= UBRK_WORD_NONE && status < UBRK_WORD_NONE_LIMIT) { + return *isolate->factory()->NewStringFromStaticChars("none"); + } else if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) { + return ReadOnlyRoots(isolate).number_string(); + } else if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) { + return *isolate->factory()->NewStringFromStaticChars("letter"); + } else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) { + return *isolate->factory()->NewStringFromStaticChars("kana"); + } else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) { + return *isolate->factory()->NewStringFromStaticChars("ideo"); + } else { + return *isolate->factory()->NewStringFromStaticChars("unknown"); + } +} + } // namespace internal } // namespace v8 diff --git a/src/contexts.h b/src/contexts.h index 540e099966ccbb4b4d694899fa44c54a9bb1d76c..edfee80a02b56417b7190a5b47dc29d401b651ee 100644 --- a/src/contexts.h +++ b/src/contexts.h @@ -225,6 +225,8 @@ enum ContextLookupFlags { break_iterator_internal_next_shared_fun) \ V(INTL_V8_BREAK_ITERATOR_INTERNAL_CURRENT_SHARED_FUN, SharedFunctionInfo, \ break_iterator_internal_current_shared_fun) \ + V(INTL_V8_BREAK_ITERATOR_INTERNAL_BREAK_TYPE_SHARED_FUN, SharedFunctionInfo, \ + break_iterator_internal_break_type_shared_fun) \ V(JS_ARRAY_PACKED_SMI_ELEMENTS_MAP_INDEX, Map, \ js_array_packed_smi_elements_map) \ V(JS_ARRAY_HOLEY_SMI_ELEMENTS_MAP_INDEX, Map, \ diff --git a/src/js/intl.js b/src/js/intl.js index 59ba7e22d6b4b467d4f0985ffa5f40d5abea7876..dd043ba2152b37571c8405b628c1de678d214fbd 100644 --- a/src/js/intl.js +++ b/src/js/intl.js @@ -55,48 +55,6 @@ macro ANONYMOUS_FUNCTION(fn) (0, (fn)) endmacro -/** - * Adds bound method to the prototype of the given object. - */ -function AddBoundMethod(obj, methodName, implementation, length, type, - compat) { - %CheckIsBootstrapping(); - var internalName = %CreatePrivateSymbol(methodName); - - DEFINE_METHOD( - obj.prototype, - get [methodName]() { - if(!IS_RECEIVER(this)) { - throw %make_type_error(kIncompatibleMethodReceiver, methodName, this); - } - var receiver = %IntlUnwrapReceiver(this, type, obj, methodName, compat); - if (IS_UNDEFINED(receiver[internalName])) { - var boundMethod; - if (IS_UNDEFINED(length) || length === 2) { - boundMethod = - ANONYMOUS_FUNCTION((fst, snd) => implementation(receiver, fst, snd)); - } else if (length === 1) { - boundMethod = ANONYMOUS_FUNCTION(fst => implementation(receiver, fst)); - } else { - boundMethod = ANONYMOUS_FUNCTION((...args) => { - // DateTimeFormat.format needs to be 0 arg method, but can still - // receive an optional dateValue param. If one was provided, pass it - // along. - if (args.length > 0) { - return implementation(receiver, args[0]); - } else { - return implementation(receiver); - } - }); - } - %SetNativeFlag(boundMethod); - receiver[internalName] = boundMethod; - } - return receiver[internalName]; - } - ); -} - function IntlConstruct(receiver, constructor, create, newTarget, args, compat) { var locales = args[0]; @@ -1141,17 +1099,6 @@ DEFINE_METHOD( ); -/** - * Returns type of the current break. - */ -function breakType(iterator) { - return %BreakIteratorBreakType(iterator); -} - - -AddBoundMethod(GlobalIntlv8BreakIterator, 'breakType', breakType, 0, - BREAK_ITERATOR_TYPE, false); - // Save references to Intl objects and methods we use, for added security. var savedObjects = { __proto__: null, diff --git a/src/objects/intl-objects.h b/src/objects/intl-objects.h index 18b6c15e0302c8c54917769bba36720da81c5644..4dce5c19d14b6c6659c5dcf37adc54df7d52a31d 100644 --- a/src/objects/intl-objects.h +++ b/src/objects/intl-objects.h @@ -200,6 +200,7 @@ class V8BreakIterator { V(kBoundFirst, kPointerSize) \ V(kBoundNext, kPointerSize) \ V(kBoundCurrent, kPointerSize) \ + V(kBoundBreakType, kPointerSize) \ V(kSize, 0) DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, BREAK_ITERATOR_FIELDS) @@ -223,6 +224,7 @@ class V8BreakIterator { static const int kBoundFirstIndex = 3; static const int kBoundNextIndex = 4; static const int kBoundCurrentIndex = 5; + static const int kBoundBreakTypeIndex = 6; private: V8BreakIterator(); diff --git a/src/runtime/runtime-intl.cc b/src/runtime/runtime-intl.cc index d32ee664992bb985e3cc275061487f804473974b..6bb2937aa2f5ffa5fef524b1ed3ca270eb593e65 100644 --- a/src/runtime/runtime-intl.cc +++ b/src/runtime/runtime-intl.cc @@ -43,7 +43,6 @@ #include "unicode/numfmt.h" #include "unicode/numsys.h" #include "unicode/plurrule.h" -#include "unicode/rbbi.h" #include "unicode/smpdtfmt.h" #include "unicode/timezone.h" #include "unicode/uchar.h" @@ -401,37 +400,6 @@ RUNTIME_FUNCTION(Runtime_CreateBreakIterator) { return *local_object; } -RUNTIME_FUNCTION(Runtime_BreakIteratorBreakType) { - HandleScope scope(isolate); - - DCHECK_EQ(1, args.length()); - - CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0); - - icu::BreakIterator* break_iterator = - V8BreakIterator::UnpackBreakIterator(break_iterator_holder); - CHECK_NOT_NULL(break_iterator); - - // 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()->NewStringFromStaticChars("none"); - } else if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) { - return ReadOnlyRoots(isolate).number_string(); - } else if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) { - return *isolate->factory()->NewStringFromStaticChars("letter"); - } else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) { - return *isolate->factory()->NewStringFromStaticChars("kana"); - } else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) { - return *isolate->factory()->NewStringFromStaticChars("ideo"); - } else { - return *isolate->factory()->NewStringFromStaticChars("unknown"); - } -} - RUNTIME_FUNCTION(Runtime_ToLocaleDateTime) { HandleScope scope(isolate); diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index 7fb86c31ddcc8cff54047c8dd0bede5cbaa68920..262792f3985d805f720a3e2698aaf383e2adad65 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -200,7 +200,6 @@ namespace internal { #ifdef V8_INTL_SUPPORT #define FOR_EACH_INTRINSIC_INTL(F) \ F(AvailableLocalesOf, 1, 1) \ - F(BreakIteratorBreakType, 1, 1) \ F(CanonicalizeLanguageTag, 1, 1) \ F(CollatorResolvedOptions, 1, 1) \ F(CreateBreakIterator, 3, 1) \