Commit 6b66beba authored by Ujjwal Sharma's avatar Ujjwal Sharma Committed by Commit Bot

[intl] Port V8BreakIterator.prototype.breakType to C++

This increases the size of a V8BreakIterator instance by a word to store
the breakType function.

The instance to be bound is stored on the context of this builtin function.
This CL removes the AddBoundMethod helper from intl.js

Bug: v8:5751
Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng
Change-Id: I4e4df2632990300b91eafda680d414e0b373825b
Reviewed-on: https://chromium-review.googlesource.com/1194803Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55501}
parent 32838756
......@@ -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);
}
}
{
......
......@@ -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 */ \
......
......@@ -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
......@@ -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, \
......
......@@ -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,
......
......@@ -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();
......
......@@ -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);
......
......@@ -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) \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment