Backed out 3 changesets (bug 1473229) for causing bustages in ICUStubs.h CLOSED TREE

Backed out changeset 953a2bd4220b (bug 1473229)
Backed out changeset f3a2031bde94 (bug 1473229)
Backed out changeset 5109ce5a4b44 (bug 1473229)
This commit is contained in:
Mihai Alexandru Michis 2019-07-09 12:07:22 +03:00
parent 8700d1754a
commit 57a64c3906
13 changed files with 139 additions and 427 deletions

View File

@ -14,7 +14,7 @@ MOZ_ARG_WITH_BOOL(system-icu,
MOZ_SYSTEM_ICU=1)
if test -n "$MOZ_SYSTEM_ICU"; then
PKG_CHECK_MODULES(MOZ_ICU, icu-i18n >= 64.1)
PKG_CHECK_MODULES(MOZ_ICU, icu-i18n >= 63.1)
CFLAGS="$CFLAGS $MOZ_ICU_CFLAGS"
CXXFLAGS="$CXXFLAGS $MOZ_ICU_CFLAGS"
AC_DEFINE(MOZ_SYSTEM_ICU)

View File

@ -97,7 +97,6 @@ included_inclnames_to_ignore = set([
'unicode/udatpg.h', # ICU
'unicode/udisplaycontext.h', # ICU
'unicode/uenum.h', # ICU
'unicode/uformattedvalue.h', # ICU
'unicode/uloc.h', # ICU
'unicode/unistr.h', # ICU
'unicode/unorm2.h', # ICU

View File

@ -1330,7 +1330,6 @@ if CONFIG['MOZ_SYSTEM_ICU']:
'unicode/udatpg.h',
'unicode/udisplaycontext.h',
'unicode/uenum.h',
'unicode/uformattedvalue.h',
'unicode/unistr.h',
'unicode/unorm.h',
'unicode/unum.h',

View File

@ -946,13 +946,10 @@ bool js::intl_FormatDateTime(JSContext* cx, unsigned argc, Value* vp) {
Rooted<DateTimeFormatObject*> dateTimeFormat(cx);
dateTimeFormat = &args[0].toObject().as<DateTimeFormatObject>();
bool formatToParts = args[2].toBoolean();
ClippedTime x = TimeClip(args[1].toNumber());
if (!x.isValid()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_DATE_NOT_FINITE, "DateTimeFormat",
formatToParts ? "formatToParts" : "format");
JSMSG_DATE_NOT_FINITE, "DateTimeFormat");
return false;
}
@ -971,6 +968,7 @@ bool js::intl_FormatDateTime(JSContext* cx, unsigned argc, Value* vp) {
}
// Use the UDateFormat to actually format the time stamp.
return formatToParts ? intl_FormatToPartsDateTime(cx, df, x, args.rval())
: intl_FormatDateTime(cx, df, x, args.rval());
return args[2].toBoolean()
? intl_FormatToPartsDateTime(cx, df, x, args.rval())
: intl_FormatDateTime(cx, df, x, args.rval());
}

View File

@ -28,7 +28,6 @@
# include "unicode/udatpg.h"
# include "unicode/udisplaycontext.h"
# include "unicode/uenum.h"
# include "unicode/uformattedvalue.h"
# include "unicode/uloc.h"
# include "unicode/unum.h"
# include "unicode/unumsys.h"
@ -47,6 +46,8 @@
#if !ENABLE_INTL_API
# define U_ICU_VERSION_MAJOR_NUM 64
enum UErrorCode {
U_ZERO_ERROR,
U_BUFFER_OVERFLOW_ERROR,
@ -673,74 +674,6 @@ inline int32_t ureldatefmt_formatNumeric(
MOZ_CRASH("ureldatefmt_formatNumeric: Intl API disabled");
}
struct UFormattedRelativeDateTime;
inline UFormattedRelativeDateTime* ureldatefmt_openResult(UErrorCode* status) {
MOZ_CRASH("ureldatefmt_openResult: Intl API disabled");
}
inline void ureldatefmt_closeResult(UFormattedRelativeDateTime* ufrdt) {
MOZ_CRASH("ureldatefmt_closeResult: Intl API disabled");
}
inline void ureldatefmt_formatToResult(
const URelativeDateTimeFormatter* reldatefmt, double offset,
URelativeDateTimeUnit unit, UFormattedRelativeDateTime* result,
UErrorCode* status) {
MOZ_CRASH("ureldatefmt_formatToResult: Intl API disabled");
}
inline void ureldatefmt_formatNumericToResult(
const URelativeDateTimeFormatter* reldatefmt, double offset,
URelativeDateTimeUnit unit, UFormattedRelativeDateTime* result,
UErrorCode* status) {
MOZ_CRASH("ureldatefmt_formatToResult: Intl API disabled");
}
struct UFormattedValue;
inline const UFormattedValue* ureldatefmt_resultAsValue(
const UFormattedRelativeDateTime* ufrdt, UErrorCode* status) {
MOZ_CRASH("ureldatefmt_resultAsValue: Intl API disabled");
}
inline const UChar* ufmtval_getString(const UFormattedValue* ufmtval,
int32_t* pLength, UErrorCode* status) {
MOZ_CRASH("ufmtval_getString: Intl API disabled");
}
inline UConstrainedFieldPosition* ucfpos_open(UErrorCode* status) {
MOZ_CRASH("ucfpos_open: Intl API disabled");
}
inline void ucfpos_close(UConstrainedFieldPosition* ucfpos) {
MOZ_CRASH("ucfpos_close: Intl API disabled");
}
typedef enum UFieldCategory { UFIELD_CATEGORY_NUMBER } UFieldCategory;
inline void ucfpos_constrainCategory(UConstrainedFieldPosition* ucfpos,
int32_t category, UErrorCode* status) {
MOZ_CRASH("ucfpos_constrainCategory: Intl API disabled");
}
inline bool ufmtval_nextPosition(const UFormattedValue* ufmtval,
UConstrainedFieldPosition* ucfpos,
UErrorCode* status) {
MOZ_CRASH("ufmtval_nextPosition: Intl API disabled");
}
inline int32_t ucfpos_getField(const UConstrainedFieldPosition* ucfpos,
UErrorCode* status) {
MOZ_CRASH("ucfpos_getField: Intl API disabled");
}
inline void ucfpos_getIndexes(const UConstrainedFieldPosition* ucfpos,
int32_t* pStart, int32_t* pLimit,
UErrorCode* status) {
MOZ_CRASH("ucfpos_getIndexes: Intl API disabled");
}
#endif // !ENABLE_INTL_API
#endif /* builtin_intl_ICUStubs_h */

View File

@ -433,8 +433,10 @@ static bool intl_FormatNumber(JSContext* cx, UNumberFormat* nf, double x,
return true;
}
static intl::FieldType GetFieldTypeForNumberField(UNumberFormatFields fieldName,
double d) {
using FieldType = ImmutablePropertyNamePtr JSAtomState::*;
static FieldType GetFieldTypeForNumberField(UNumberFormatFields fieldName,
double d) {
// See intl/icu/source/i18n/unicode/unum.h for a detailed field list. This
// list is deliberately exhaustive: cases might have to be added/removed if
// this code is compiled with a different ICU with more UNumberFormatFields
@ -494,6 +496,7 @@ static intl::FieldType GetFieldTypeForNumberField(UNumberFormatFields fieldName,
break;
#ifndef U_HIDE_DRAFT_API
# if U_ICU_VERSION_MAJOR_NUM >= 64
case UNUM_MEASURE_UNIT_FIELD:
MOZ_ASSERT_UNREACHABLE(
"unexpected measure unit field found, even though "
@ -507,6 +510,7 @@ static intl::FieldType GetFieldTypeForNumberField(UNumberFormatFields fieldName,
"we don't use any user-defined patterns that "
"would require a compact number notation");
break;
# endif
#endif
#ifndef U_HIDE_DEPRECATED_API
@ -524,29 +528,72 @@ static intl::FieldType GetFieldTypeForNumberField(UNumberFormatFields fieldName,
return nullptr;
}
bool js::intl::NumberFormatFields::append(int32_t field, int32_t begin,
int32_t end) {
MOZ_ASSERT(begin >= 0);
MOZ_ASSERT(end >= 0);
MOZ_ASSERT(begin < end, "erm, aren't fields always non-empty?");
static bool intl_FormatNumberToParts(JSContext* cx, UNumberFormat* nf, double x,
MutableHandleValue result) {
UErrorCode status = U_ZERO_ERROR;
FieldType type =
GetFieldTypeForNumberField(UNumberFormatFields(field), number_);
return fields_.emplaceBack(uint32_t(begin), uint32_t(end), type);
}
UFieldPositionIterator* fpositer = ufieldpositer_open(&status);
if (U_FAILURE(status)) {
intl::ReportInternalError(cx);
return false;
}
ArrayObject* js::intl::NumberFormatFields::toArray(JSContext* cx,
HandleString overallResult,
FieldType unitType) {
// Merge sort the fields vector. Expand the vector to have scratch space for
// performing the sort.
size_t fieldsLen = fields_.length();
if (!fields_.resizeUninitialized(fieldsLen * 2)) {
return nullptr;
MOZ_ASSERT(fpositer);
ScopedICUObject<UFieldPositionIterator, ufieldpositer_close> toClose(
fpositer);
RootedString overallResult(cx, PartitionNumberPattern(cx, nf, &x, fpositer));
if (!overallResult) {
return false;
}
RootedArrayObject partsArray(cx, NewDenseEmptyArray(cx));
if (!partsArray) {
return false;
}
// First, vacuum up fields in the overall formatted string.
struct Field {
uint32_t begin;
uint32_t end;
FieldType type;
// Needed for vector-resizing scratch space.
Field() = default;
Field(uint32_t begin, uint32_t end, FieldType type)
: begin(begin), end(end), type(type) {}
};
using FieldsVector = Vector<Field, 16>;
FieldsVector fields(cx);
int32_t fieldInt, beginIndexInt, endIndexInt;
while ((fieldInt = ufieldpositer_next(fpositer, &beginIndexInt,
&endIndexInt)) >= 0) {
MOZ_ASSERT(beginIndexInt >= 0);
MOZ_ASSERT(endIndexInt >= 0);
MOZ_ASSERT(beginIndexInt < endIndexInt,
"erm, aren't fields always non-empty?");
FieldType type =
GetFieldTypeForNumberField(UNumberFormatFields(fieldInt), x);
if (!fields.emplaceBack(uint32_t(beginIndexInt), uint32_t(endIndexInt),
type)) {
return false;
}
}
// Second, merge sort the fields vector. Expand the vector to have scratch
// space for performing the sort.
size_t fieldsLen = fields.length();
if (!fields.resizeUninitialized(fieldsLen * 2)) {
return false;
}
MOZ_ALWAYS_TRUE(MergeSort(
fields_.begin(), fieldsLen, fields_.begin() + fieldsLen,
fields.begin(), fieldsLen, fields.begin() + fieldsLen,
[](const Field& left, const Field& right, bool* lessOrEqual) {
// Sort first by begin index, then to place
// enclosing fields before nested fields.
@ -556,13 +603,13 @@ ArrayObject* js::intl::NumberFormatFields::toArray(JSContext* cx,
}));
// Deallocate the scratch space.
if (!fields_.resize(fieldsLen)) {
return nullptr;
if (!fields.resize(fieldsLen)) {
return false;
}
// Then iterate over the sorted field list to generate a sequence of parts
// (what ECMA-402 actually exposes). A part is a maximal character sequence
// entirely within no field or a single most-nested field.
// Third, iterate over the sorted field list to generate a sequence of
// parts (what ECMA-402 actually exposes). A part is a maximal character
// sequence entirely within no field or a single most-nested field.
//
// Diagrams may be helpful to illustrate how fields map to parts. Consider
// formatting -19,766,580,028,249.41, the US national surplus (negative
@ -767,17 +814,12 @@ ArrayObject* js::intl::NumberFormatFields::toArray(JSContext* cx,
RootedObject singlePart(cx);
RootedValue propVal(cx);
RootedArrayObject partsArray(cx, NewDenseEmptyArray(cx));
if (!partsArray) {
return nullptr;
}
PartGenerator gen(cx, fields_, overallResult->length());
PartGenerator gen(cx, fields, overallResult->length());
do {
bool hasPart;
Part part;
if (!gen.nextPart(&hasPart, &part)) {
return nullptr;
return false;
}
if (!hasPart) {
@ -791,35 +833,28 @@ ArrayObject* js::intl::NumberFormatFields::toArray(JSContext* cx,
singlePart = NewBuiltinClassInstance<PlainObject>(cx);
if (!singlePart) {
return nullptr;
return false;
}
propVal.setString(cx->names().*type);
if (!DefineDataProperty(cx, singlePart, cx->names().type, propVal)) {
return nullptr;
return false;
}
JSLinearString* partSubstr = NewDependentString(
cx, overallResult, lastEndIndex, endIndex - lastEndIndex);
if (!partSubstr) {
return nullptr;
return false;
}
propVal.setString(partSubstr);
if (!DefineDataProperty(cx, singlePart, cx->names().value, propVal)) {
return nullptr;
}
if (unitType != nullptr && type != &JSAtomState::literal) {
propVal.setString(cx->names().*unitType);
if (!DefineDataProperty(cx, singlePart, cx->names().unit, propVal)) {
return nullptr;
}
return false;
}
propVal.setObject(*singlePart);
if (!DefineDataElement(cx, partsArray, partIndex, propVal)) {
return nullptr;
return false;
}
lastEndIndex = endIndex;
@ -829,45 +864,7 @@ ArrayObject* js::intl::NumberFormatFields::toArray(JSContext* cx,
MOZ_ASSERT(lastEndIndex == overallResult->length(),
"result array must partition the entire string");
return partsArray;
}
static bool intl_FormatNumberToParts(JSContext* cx, UNumberFormat* nf, double x,
MutableHandleValue result) {
UErrorCode status = U_ZERO_ERROR;
UFieldPositionIterator* fpositer = ufieldpositer_open(&status);
if (U_FAILURE(status)) {
intl::ReportInternalError(cx);
return false;
}
MOZ_ASSERT(fpositer);
ScopedICUObject<UFieldPositionIterator, ufieldpositer_close> toClose(
fpositer);
RootedString overallResult(cx, PartitionNumberPattern(cx, nf, &x, fpositer));
if (!overallResult) {
return false;
}
// Vacuum up fields in the overall formatted string.
intl::NumberFormatFields fields(cx, x);
int32_t field, beginIndex, endIndex;
while ((field = ufieldpositer_next(fpositer, &beginIndex, &endIndex)) >= 0) {
if (!fields.append(field, beginIndex, endIndex)) {
return false;
}
}
ArrayObject* array = fields.toArray(cx, overallResult, nullptr);
if (!array) {
return false;
}
result.setObject(*array);
result.setObject(*partsArray);
return true;
}

View File

@ -12,15 +12,11 @@
#include <stdint.h>
#include "builtin/SelfHostingDefines.h"
#include "gc/Barrier.h"
#include "js/Class.h"
#include "js/Vector.h"
#include "vm/NativeObject.h"
#include "vm/Runtime.h"
namespace js {
class ArrayObject;
class FreeOp;
class NumberFormatObject : public NativeObject {
@ -88,40 +84,6 @@ extern MOZ_MUST_USE bool intl_numberingSystem(JSContext* cx, unsigned argc,
extern MOZ_MUST_USE bool intl_FormatNumber(JSContext* cx, unsigned argc,
Value* vp);
namespace intl {
using FieldType = js::ImmutablePropertyNamePtr JSAtomState::*;
struct Field {
uint32_t begin;
uint32_t end;
FieldType type;
// Needed for vector-resizing scratch space.
Field() = default;
Field(uint32_t begin, uint32_t end, FieldType type)
: begin(begin), end(end), type(type) {}
};
class NumberFormatFields {
using FieldsVector = Vector<Field, 16>;
FieldsVector fields_;
double number_;
public:
NumberFormatFields(JSContext* cx, double number)
: fields_(cx), number_(number) {}
MOZ_MUST_USE bool append(int32_t field, int32_t begin, int32_t end);
MOZ_MUST_USE ArrayObject* toArray(JSContext* cx,
JS::HandleString overallResult,
FieldType unitType);
};
} // namespace intl
} // namespace js
#endif /* builtin_intl_NumberFormat_h */

View File

@ -13,19 +13,19 @@
#include "builtin/intl/CommonFunctions.h"
#include "builtin/intl/ICUStubs.h"
#include "builtin/intl/NumberFormat.h"
#include "builtin/intl/ScopedICUObject.h"
#include "gc/FreeOp.h"
#include "js/CharacterEncoding.h"
#include "js/PropertySpec.h"
#include "vm/GlobalObject.h"
#include "vm/JSContext.h"
#include "vm/StringType.h"
#include "vm/NativeObject-inl.h"
using namespace js;
using mozilla::IsNegativeZero;
using js::intl::CallICU;
using js::intl::GetAvailableLocales;
using js::intl::IcuLocale;
@ -63,10 +63,6 @@ static const JSFunctionSpec relativeTimeFormat_methods[] = {
JS_SELF_HOSTED_FN("resolvedOptions",
"Intl_RelativeTimeFormat_resolvedOptions", 0, 0),
JS_SELF_HOSTED_FN("format", "Intl_RelativeTimeFormat_format", 2, 0),
#ifndef U_HIDE_DRAFT_API
JS_SELF_HOSTED_FN("formatToParts", "Intl_RelativeTimeFormat_formatToParts",
2, 0),
#endif
JS_FN(js_toSource_str, relativeTimeFormat_toSource, 0, 0), JS_FS_END};
static const JSPropertySpec relativeTimeFormat_properties[] = {
@ -261,176 +257,14 @@ enum class RelativeTimeNumeric {
Auto,
};
static bool intl_FormatRelativeTime(JSContext* cx,
URelativeDateTimeFormatter* rtf, double t,
URelativeDateTimeUnit unit,
RelativeTimeNumeric numeric,
MutableHandleValue result) {
JSString* str = CallICU(
cx,
[rtf, t, unit, numeric](UChar* chars, int32_t size, UErrorCode* status) {
auto fmt = numeric == RelativeTimeNumeric::Auto
? ureldatefmt_format
: ureldatefmt_formatNumeric;
return fmt(rtf, t, unit, chars, size, status);
});
if (!str) {
return false;
}
result.setString(str);
return true;
}
#ifndef U_HIDE_DRAFT_API
static bool intl_FormatToPartsRelativeTime(JSContext* cx,
URelativeDateTimeFormatter* rtf,
double t, URelativeDateTimeUnit unit,
RelativeTimeNumeric numeric,
MutableHandleValue result) {
UErrorCode status = U_ZERO_ERROR;
UFormattedRelativeDateTime* formatted = ureldatefmt_openResult(&status);
if (U_FAILURE(status)) {
intl::ReportInternalError(cx);
return false;
}
ScopedICUObject<UFormattedRelativeDateTime, ureldatefmt_closeResult> toClose(
formatted);
if (numeric == RelativeTimeNumeric::Auto) {
ureldatefmt_formatToResult(rtf, t, unit, formatted, &status);
} else {
ureldatefmt_formatNumericToResult(rtf, t, unit, formatted, &status);
}
if (U_FAILURE(status)) {
intl::ReportInternalError(cx);
return false;
}
const UFormattedValue* formattedValue =
ureldatefmt_resultAsValue(formatted, &status);
if (U_FAILURE(status)) {
intl::ReportInternalError(cx);
return false;
}
int32_t strLength;
const char16_t* str = ufmtval_getString(formattedValue, &strLength, &status);
if (U_FAILURE(status)) {
intl::ReportInternalError(cx);
return false;
}
MOZ_ASSERT(strLength >= 0);
RootedString overallResult(cx,
NewStringCopyN<CanGC>(cx, str, size_t(strLength)));
if (!overallResult) {
return false;
}
intl::FieldType unitType;
switch (unit) {
case UDAT_REL_UNIT_SECOND:
unitType = &JSAtomState::second;
break;
case UDAT_REL_UNIT_MINUTE:
unitType = &JSAtomState::minute;
break;
case UDAT_REL_UNIT_HOUR:
unitType = &JSAtomState::hour;
break;
case UDAT_REL_UNIT_DAY:
unitType = &JSAtomState::day;
break;
case UDAT_REL_UNIT_WEEK:
unitType = &JSAtomState::week;
break;
case UDAT_REL_UNIT_MONTH:
unitType = &JSAtomState::month;
break;
case UDAT_REL_UNIT_QUARTER:
unitType = &JSAtomState::quarter;
break;
case UDAT_REL_UNIT_YEAR:
unitType = &JSAtomState::year;
break;
default:
MOZ_CRASH("unexpected relative time unit");
}
UConstrainedFieldPosition* fpos = ucfpos_open(&status);
if (U_FAILURE(status)) {
intl::ReportInternalError(cx);
return false;
}
ScopedICUObject<UConstrainedFieldPosition, ucfpos_close> toCloseFpos(fpos);
// The possible field position categories are UFIELD_CATEGORY_NUMBER and
// UFIELD_CATEGORY_RELATIVE_DATETIME. For the parts array we only need to
// iterate over the number formatted fields.
ucfpos_constrainCategory(fpos, UFIELD_CATEGORY_NUMBER, &status);
if (U_FAILURE(status)) {
intl::ReportInternalError(cx);
return false;
}
intl::NumberFormatFields fields(cx, t);
while (true) {
bool hasMore = ufmtval_nextPosition(formattedValue, fpos, &status);
if (U_FAILURE(status)) {
intl::ReportInternalError(cx);
return false;
}
if (!hasMore) {
break;
}
int32_t field = ucfpos_getField(fpos, &status);
if (U_FAILURE(status)) {
intl::ReportInternalError(cx);
return false;
}
int32_t beginIndex, endIndex;
ucfpos_getIndexes(fpos, &beginIndex, &endIndex, &status);
if (U_FAILURE(status)) {
intl::ReportInternalError(cx);
return false;
}
if (!fields.append(field, beginIndex, endIndex)) {
return false;
}
}
ArrayObject* array = fields.toArray(cx, overallResult, unitType);
if (!array) {
return false;
}
result.setObject(*array);
return true;
}
#endif
bool js::intl_FormatRelativeTime(JSContext* cx, unsigned argc, Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp);
MOZ_ASSERT(args.length() == 5);
MOZ_ASSERT(args.length() == 4);
Rooted<RelativeTimeFormatObject*> relativeTimeFormat(cx);
relativeTimeFormat = &args[0].toObject().as<RelativeTimeFormatObject>();
bool formatToParts = args[4].toBoolean();
// PartitionRelativeTimePattern, step 4.
double t = args[1].toNumber();
if (!mozilla::IsFinite(t)) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_DATE_NOT_FINITE, "RelativeTimeFormat",
formatToParts ? "formatToParts" : "format");
return false;
}
// Obtain a cached URelativeDateTimeFormatter object.
constexpr auto RT_FORMAT_SLOT =
@ -453,7 +287,6 @@ bool js::intl_FormatRelativeTime(JSContext* cx, unsigned argc, Value* vp) {
return false;
}
// PartitionRelativeTimePattern, step 5.
if (StringEqualsAscii(unit, "second") ||
StringEqualsAscii(unit, "seconds")) {
relDateTimeUnit = UDAT_REL_UNIT_SECOND;
@ -475,16 +308,10 @@ bool js::intl_FormatRelativeTime(JSContext* cx, unsigned argc, Value* vp) {
} else if (StringEqualsAscii(unit, "quarter") ||
StringEqualsAscii(unit, "quarters")) {
relDateTimeUnit = UDAT_REL_UNIT_QUARTER;
} else if (StringEqualsAscii(unit, "year") ||
StringEqualsAscii(unit, "years")) {
relDateTimeUnit = UDAT_REL_UNIT_YEAR;
} else {
if (auto unitChars = StringToNewUTF8CharsZ(cx, *unit)) {
JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
JSMSG_INVALID_OPTION_VALUE, "unit",
unitChars.get());
}
return false;
MOZ_ASSERT(StringEqualsAscii(unit, "year") ||
StringEqualsAscii(unit, "years"));
relDateTimeUnit = UDAT_REL_UNIT_YEAR;
}
}
@ -503,15 +330,18 @@ bool js::intl_FormatRelativeTime(JSContext* cx, unsigned argc, Value* vp) {
}
}
#ifndef U_HIDE_DRAFT_API
return formatToParts
? intl_FormatToPartsRelativeTime(cx, rtf, t, relDateTimeUnit,
relDateTimeNumeric, args.rval())
: intl_FormatRelativeTime(cx, rtf, t, relDateTimeUnit,
relDateTimeNumeric, args.rval());
#else
MOZ_ASSERT(!formatToParts);
return intl_FormatRelativeTime(cx, rtf, t, relDateTimeUnit,
relDateTimeNumeric, args.rval());
#endif
JSString* str =
CallICU(cx, [rtf, t, relDateTimeUnit, relDateTimeNumeric](
UChar* chars, int32_t size, UErrorCode* status) {
auto fmt = relDateTimeNumeric == RelativeTimeNumeric::Auto
? ureldatefmt_format
: ureldatefmt_formatNumeric;
return fmt(rtf, t, relDateTimeUnit, chars, size, status);
});
if (!str) {
return false;
}
args.rval().setString(str);
return true;
}

View File

@ -62,7 +62,7 @@ extern MOZ_MUST_USE bool intl_RelativeTimeFormat_availableLocales(
* |numeric| should be "always" or "auto".
*
* Usage: formatted = intl_FormatRelativeTime(relativeTimeFormat, t,
* unit, numeric, formatToParts)
* unit, numeric)
*/
extern MOZ_MUST_USE bool intl_FormatRelativeTime(JSContext* cx, unsigned argc,
JS::Value* vp);

View File

@ -201,48 +201,42 @@ function Intl_RelativeTimeFormat_format(value, unit) {
// Step 4.
let u = ToString(unit);
// Step 5.
return intl_FormatRelativeTime(relativeTimeFormat, t, u, internals.numeric,
false);
}
/**
* Returns an Array composed of the components of a relative date formatted
* according to the effective locale and the formatting options of this
* RelativeTimeFormat object.
*
* Spec: ECMAScript 402 API, RelativeTImeFormat, 1.4.4.
*/
function Intl_RelativeTimeFormat_formatToParts(value, unit) {
// Step 1.
let relativeTimeFormat = this;
// Step 2.
if (!IsObject(relativeTimeFormat) ||
(relativeTimeFormat = GuardToRelativeTimeFormat(relativeTimeFormat)) === null)
{
return callFunction(CallRelativeTimeFormatMethodIfWrapped, this, value, unit,
"Intl_RelativeTimeFormat_formatToParts");
// PartitionRelativeTimePattern, step 4.
if (!Number_isFinite(t)) {
ThrowRangeError(JSMSG_DATE_NOT_FINITE, "RelativeTimeFormat");
}
// Ensure the RelativeTimeFormat internals are resolved.
var internals = getRelativeTimeFormatInternals(relativeTimeFormat);
// Step 3.
let t = ToNumber(value);
// Step 4.
let u = ToString(unit);
// PartitionRelativeTimePattern, step 5.
switch (u) {
case "second":
case "seconds":
case "minute":
case "minutes":
case "hour":
case "hours":
case "day":
case "days":
case "week":
case "weeks":
case "month":
case "months":
case "quarter":
case "quarters":
case "year":
case "years":
break;
default:
ThrowRangeError(JSMSG_INVALID_OPTION_VALUE, "unit", u);
}
// Step 5.
return intl_FormatRelativeTime(relativeTimeFormat, t, u, internals.numeric,
true);
return intl_FormatRelativeTime(relativeTimeFormat, t, u, internals.numeric);
}
/**
* Returns the resolved options for a RelativeTimeFormat object.
*
* Spec: ECMAScript 402 API, RelativeTimeFormat, 1.4.5.
* Spec: ECMAScript 402 API, RelativeTimeFormat, 1.4.4.
*/
function Intl_RelativeTimeFormat_resolvedOptions() {
// Step 1.

View File

@ -519,7 +519,7 @@ MSG_DEF(JSMSG_TESTING_SCRIPTS_ONLY, 0, JSEXN_TYPEERR, "only works on scripts")
MSG_DEF(JSMSG_TRACELOGGER_ENABLE_FAIL, 1, JSEXN_ERR, "enabling tracelogger failed: {0}")
// Intl
MSG_DEF(JSMSG_DATE_NOT_FINITE, 2, JSEXN_RANGEERR, "date value is not finite in {0}.{1}()")
MSG_DEF(JSMSG_DATE_NOT_FINITE, 1, JSEXN_RANGEERR, "date value is not finite in {0}.format()")
MSG_DEF(JSMSG_INTERNAL_INTL_ERROR, 0, JSEXN_ERR, "internal error while computing Intl data")
MSG_DEF(JSMSG_INVALID_CURRENCY_CODE, 1, JSEXN_RANGEERR, "invalid currency code in NumberFormat(): {0}")
MSG_DEF(JSMSG_INVALID_DIGITS_VALUE, 1, JSEXN_RANGEERR, "invalid digits value: {0}")

View File

@ -16,7 +16,6 @@ slow script test262/built-ins/decodeURIComponent/S15.1.3.2_A2.5_T1.js
skip-if((xulRuntime.XPCOMABI.match(/aarch64/))&&(xulRuntime.OS=="WINNT")) script non262/Math/fround.js
skip-if((xulRuntime.XPCOMABI.match(/aarch64/))&&(xulRuntime.OS=="WINNT")) script non262/Math/log2-approx.js
###########################################################################
# Generated jstests.list for test262 when inline |reftest| isn't possible #
###########################################################################
@ -437,6 +436,9 @@ skip script test262/annexB/built-ins/Function/createdynfn-no-line-terminator-htm
# https://bugzilla.mozilla.org/show_bug.cgi?id=1462745
skip script test262/annexB/language/function-code/block-decl-nested-blocks-with-fun-decl.js
# https://bugzilla.mozilla.org/show_bug.cgi?id=1473229
skip include test262/intl402/RelativeTimeFormat/prototype/formatToParts/jstests.list
# https://bugzilla.mozilla.org/show_bug.cgi?id=1508683
skip script test262/built-ins/RegExp/prototype/multiline/cross-realm.js
skip script test262/built-ins/RegExp/prototype/global/cross-realm.js

View File

@ -341,7 +341,6 @@
MACRO(proto, proto, "__proto__") \
MACRO(prototype, prototype, "prototype") \
MACRO(proxy, proxy, "proxy") \
MACRO(quarter, quarter, "quarter") \
MACRO(raw, raw, "raw") \
MACRO(reason, reason, "reason") \
MACRO(RegExpBuiltinExec, RegExpBuiltinExec, "RegExpBuiltinExec") \
@ -457,7 +456,6 @@
MACRO(WeakSetConstructorInit, WeakSetConstructorInit, \
"WeakSetConstructorInit") \
MACRO(WeakSet_add, WeakSet_add, "WeakSet_add") \
MACRO(week, week, "week") \
MACRO(weekday, weekday, "weekday") \
MACRO(weekendEnd, weekendEnd, "weekendEnd") \
MACRO(weekendStart, weekendStart, "weekendStart") \