зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
4a8f76c4de
Коммит
46828c7015
|
@ -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);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче