Bug 1570370 - Part 2: Port Intl.Locale to C++. r=jwalden

Differential Revision: https://phabricator.services.mozilla.com/D40068

--HG--
extra : moz-landing-system : lando
This commit is contained in:
André Bargull 2019-10-11 19:24:41 +00:00
Родитель 4a8f76c4de
Коммит 46828c7015
9 изменённых файлов: 1450 добавлений и 3 удалений

Просмотреть файл

@ -750,7 +750,7 @@ static const uint32_t JSCLASS_FOREGROUND_FINALIZE =
// application.
static const uint32_t JSCLASS_GLOBAL_APPLICATION_SLOTS = 5;
static const uint32_t JSCLASS_GLOBAL_SLOT_COUNT =
JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 2 + 40;
JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 2 + 41;
#define JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(n) \
(JSCLASS_IS_GLOBAL | \

Просмотреть файл

@ -56,6 +56,11 @@ bool IsStructurallyValidLanguageTag(
std::all_of(str, str + length, mozilla::IsAsciiLowercaseAlpha<CharT>);
}
template bool IsStructurallyValidLanguageTag(
const mozilla::Range<const Latin1Char>& language);
template bool IsStructurallyValidLanguageTag(
const mozilla::Range<const char16_t>& language);
template <typename CharT>
bool IsStructurallyValidScriptTag(const mozilla::Range<const CharT>& script) {
// Tell the analysis the |std::all_of| function can't GC.
@ -69,6 +74,11 @@ bool IsStructurallyValidScriptTag(const mozilla::Range<const CharT>& script) {
mozilla::IsAsciiLowercaseAlpha<CharT>);
}
template bool IsStructurallyValidScriptTag(
const mozilla::Range<const Latin1Char>& script);
template bool IsStructurallyValidScriptTag(
const mozilla::Range<const char16_t>& script);
template <typename CharT>
bool IsStructurallyValidRegionTag(const mozilla::Range<const CharT>& region) {
// Tell the analysis the |std::all_of| function can't GC.
@ -83,6 +93,11 @@ bool IsStructurallyValidRegionTag(const mozilla::Range<const CharT>& region) {
std::all_of(str, str + length, mozilla::IsAsciiDigit<CharT>));
}
template bool IsStructurallyValidRegionTag(
const mozilla::Range<const Latin1Char>& region);
template bool IsStructurallyValidRegionTag(
const mozilla::Range<const char16_t>& region);
bool IsStructurallyValidVariantTag(const ConstCharRange& variant) {
// unicode_variant_subtag = (alphanum{5,8} | digit alphanum{3}) ;
auto isAsciiLowercaseAlphanumeric = [](char c) {
@ -1496,5 +1511,87 @@ bool LanguageTagParser::canParseUnicodeExtensionType(
return tok.isNone();
}
bool ParseStandaloneLanguagTag(HandleLinearString str, LanguageSubtag& result) {
auto isLanguage = [](const auto* language, size_t length) {
// Tell the analysis the |std::all_of| function can't GC.
JS::AutoSuppressGCAnalysis nogc;
using T = std::remove_pointer_t<decltype(language)>;
return length >= 2 && length != 4 && length <= 8 &&
std::all_of(language, language + length, mozilla::IsAsciiAlpha<T>);
};
JS::AutoCheckCannotGC nogc;
if (str->hasLatin1Chars()) {
if (!isLanguage(str->latin1Chars(nogc), str->length())) {
return false;
}
result.set(str->latin1Range(nogc));
} else {
if (!isLanguage(str->twoByteChars(nogc), str->length())) {
return false;
}
result.set(str->twoByteRange(nogc));
}
result.toLowerCase();
return true;
}
bool ParseStandaloneScriptTag(HandleLinearString str, ScriptSubtag& result) {
auto isScript = [](const auto* script, size_t length) {
// Tell the analysis the |std::all_of| function can't GC.
JS::AutoSuppressGCAnalysis nogc;
using T = std::remove_pointer_t<decltype(script)>;
return length == ScriptLength &&
std::all_of(script, script + ScriptLength, mozilla::IsAsciiAlpha<T>);
};
JS::AutoCheckCannotGC nogc;
if (str->hasLatin1Chars()) {
if (!isScript(str->latin1Chars(nogc), str->length())) {
return false;
}
result.set(str->latin1Range(nogc));
} else {
if (!isScript(str->twoByteChars(nogc), str->length())) {
return false;
}
result.set(str->twoByteRange(nogc));
}
result.toTitleCase();
return true;
}
bool ParseStandaloneRegionTag(HandleLinearString str, RegionSubtag& result) {
auto isRegion = [](const auto* region, size_t length) {
// Tell the analysis the |std::all_of| function can't GC.
JS::AutoSuppressGCAnalysis nogc;
using T = std::remove_pointer_t<decltype(region)>;
return (length == AlphaRegionLength &&
std::all_of(region, region + AlphaRegionLength,
mozilla::IsAsciiAlpha<T>)) ||
(length == DigitRegionLength &&
std::all_of(region, region + DigitRegionLength,
mozilla::IsAsciiDigit<T>));
};
JS::AutoCheckCannotGC nogc;
if (str->hasLatin1Chars()) {
if (!isRegion(str->latin1Chars(nogc), str->length())) {
return false;
}
result.set(str->latin1Range(nogc));
} else {
if (!isRegion(str->twoByteChars(nogc), str->length())) {
return false;
}
result.set(str->twoByteRange(nogc));
}
result.toUpperCase();
return true;
}
} // namespace intl
} // namespace js

Просмотреть файл

@ -24,6 +24,7 @@
#include "js/AllocPolicy.h"
#include "js/GCAPI.h"
#include "js/Result.h"
#include "js/RootingAPI.h"
#include "js/Utility.h"
#include "js/Vector.h"
@ -682,6 +683,30 @@ class MOZ_STACK_CLASS LanguageTagParser final {
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(LanguageTagParser::TokenKind)
/**
* Parse a string as a standalone |language| tag. If |str| is a standalone
* language tag, store it in case-normalized form in |result| and return true.
* Otherwise return false.
*/
MOZ_MUST_USE bool ParseStandaloneLanguagTag(JS::Handle<JSLinearString*> str,
LanguageSubtag& result);
/**
* Parse a string as a standalone |script| tag. If |str| is a standalone script
* tag, store it in case-normalized form in |result| and return true. Otherwise
* return false.
*/
MOZ_MUST_USE bool ParseStandaloneScriptTag(JS::Handle<JSLinearString*> str,
ScriptSubtag& result);
/**
* Parse a string as a standalone |region| tag. If |str| is a standalone region
* tag, store it in case-normalized form in |result| and return true. Otherwise
* return false.
*/
MOZ_MUST_USE bool ParseStandaloneRegionTag(JS::Handle<JSLinearString*> str,
RegionSubtag& result);
} // namespace intl
} // namespace js

Просмотреть файл

@ -171,6 +171,25 @@ JSObject* js::CreateLocalePrototype(JSContext* cx, HandleObject Intl,
}
global->setReservedSlot(LOCALE_PROTO, ObjectValue(*localeProto));
{
const Value& proto = global->getReservedSlot(NATIVE_LOCALE_PROTO);
if (!proto.isUndefined()) {
MOZ_ASSERT(proto.isObject());
JS_ReportErrorASCII(
cx,
"the Locale constructor can't be added multiple times in the"
"same global");
return false;
}
}
localeProto = CreateNativeLocalePrototype(cx, intl, global);
if (!localeProto) {
return false;
}
global->setReservedSlot(NATIVE_LOCALE_PROTO, ObjectValue(*localeProto));
return true;
}

Просмотреть файл

@ -1,5 +1,5 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: set ts=8 sts=2 et sw=2 tw=80:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -33,6 +33,38 @@ extern JSObject* CreateLocalePrototype(JSContext* cx,
JS::Handle<JSObject*> Intl,
JS::Handle<GlobalObject*> global);
class NativeLocaleObject : public NativeObject {
public:
static const JSClass class_;
static constexpr uint32_t LANGUAGE_TAG_SLOT = 0;
static constexpr uint32_t BASENAME_SLOT = 1;
static constexpr uint32_t UNICODE_EXTENSION_SLOT = 2;
static constexpr uint32_t SLOT_COUNT = 3;
/**
* Returns the complete language tag, including any extensions and privateuse
* subtags.
*/
JSString* languageTag() const {
return getFixedSlot(LANGUAGE_TAG_SLOT).toString();
}
/**
* Returns the basename subtags, i.e. excluding any extensions and privateuse
* subtags.
*/
JSString* baseName() const { return getFixedSlot(BASENAME_SLOT).toString(); }
const Value& unicodeExtension() const {
return getFixedSlot(UNICODE_EXTENSION_SLOT);
}
};
extern JSObject* CreateNativeLocalePrototype(JSContext* cx,
JS::Handle<JSObject*> Intl,
JS::Handle<GlobalObject*> global);
/**
* Creates an uninitialized Intl.Locale object.
*/

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -383,6 +383,7 @@ if CONFIG['ENABLE_INTL_API']:
'builtin/intl/LanguageTag.cpp',
'builtin/intl/LanguageTagGenerated.cpp',
'builtin/intl/Locale.cpp',
'builtin/intl/NativeLocale.cpp',
'builtin/intl/NumberFormat.cpp',
'builtin/intl/PluralRules.cpp',
'builtin/intl/RelativeTimeFormat.cpp',

Просмотреть файл

@ -64,6 +64,7 @@
MACRO(byteOffset, byteOffset, "byteOffset") \
MACRO(bytes, bytes, "bytes") \
MACRO(BYTES_PER_ELEMENT, BYTES_PER_ELEMENT, "BYTES_PER_ELEMENT") \
MACRO(calendar, calendar, "calendar") \
MACRO(call, call, "call") \
MACRO(callContentFunction, callContentFunction, "callContentFunction") \
MACRO(callee, callee, "callee") \
@ -77,6 +78,7 @@
MACRO(catch, catch_, "catch") \
MACRO(class, class_, "class") \
MACRO(close, close, "close") \
MACRO(collation, collation, "collation") \
MACRO(Collator, Collator, "Collator") \
MACRO(collections, collections, "collections") \
MACRO(columnNumber, columnNumber, "columnNumber") \
@ -208,6 +210,7 @@
MACRO(hasOwnProperty, hasOwnProperty, "hasOwnProperty") \
MACRO(highWaterMark, highWaterMark, "highWaterMark") \
MACRO(hour, hour, "hour") \
MACRO(hourCycle, hourCycle, "hourCycle") \
MACRO(if, if_, "if") \
MACRO(ignoreCase, ignoreCase, "ignoreCase") \
MACRO(ignorePunctuation, ignorePunctuation, "ignorePunctuation") \
@ -257,6 +260,7 @@
MACRO(js, js, "js") \
MACRO(keys, keys, "keys") \
MACRO(label, label, "label") \
MACRO(language, language, "language") \
MACRO(lastIndex, lastIndex, "lastIndex") \
MACRO(length, length, "length") \
MACRO(let, let, "let") \
@ -313,6 +317,7 @@
MACRO(notation, notation, "notation") \
MACRO(notes, notes, "notes") \
MACRO(NumberFormat, NumberFormat, "NumberFormat") \
MACRO(numberingSystem, numberingSystem, "numberingSystem") \
MACRO(numeric, numeric, "numeric") \
MACRO(objectArguments, objectArguments, "[object Arguments]") \
MACRO(objectArray, objectArray, "[object Array]") \
@ -363,6 +368,7 @@
MACRO(RegExpStringIterator, RegExpStringIterator, "RegExp String Iterator") \
MACRO(RegExpTester, RegExpTester, "RegExpTester") \
MACRO(RegExp_prototype_Exec, RegExp_prototype_Exec, "RegExp_prototype_Exec") \
MACRO(region, region, "region") \
MACRO(Reify, Reify, "Reify") \
MACRO(reject, reject, "reject") \
MACRO(rejected, rejected, "rejected") \

Просмотреть файл

@ -96,6 +96,7 @@ class GlobalObject : public NativeObject {
PLURAL_RULES_PROTO,
RELATIVE_TIME_FORMAT_PROTO,
LOCALE_PROTO,
NATIVE_LOCALE_PROTO,
MODULE_PROTO,
IMPORT_ENTRY_PROTO,
EXPORT_ENTRY_PROTO,
@ -549,6 +550,11 @@ class GlobalObject : public NativeObject {
}
#endif // ENABLE_INTL_API
static JSObject* getOrCreateLocaleNativePrototype(
JSContext* cx, Handle<GlobalObject*> global) {
return getOrCreateObject(cx, global, NATIVE_LOCALE_PROTO, initIntlObject);
}
static bool ensureModulePrototypesCreated(JSContext* cx,
Handle<GlobalObject*> global);