author | Sebastian Hengst <archaeopteryx@coole-files.de> |
Wed, 23 Nov 2016 17:48:00 +0100 | |
changeset 323932 | 00df72027708beea7b601fdc78ca73461bbfe5e3 |
parent 323931 | 84db192b60ed0d7414746157c79d17277425c698 |
child 323933 | d29ab4cddb8299285f431ff521c64712f25ad33e |
push id | 84279 |
push user | archaeopteryx@coole-files.de |
push date | Wed, 23 Nov 2016 16:48:17 +0000 |
treeherder | mozilla-inbound@00df72027708 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | backout |
bugs | 1319464 |
milestone | 53.0a1 |
backs out | 7251919f6a2318ab715085c4162d927455bae6b7 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
js/src/builtin/Intl.cpp | file | annotate | diff | comparison | revisions | |
js/src/builtin/Intl.h | file | annotate | diff | comparison | revisions |
--- a/js/src/builtin/Intl.cpp +++ b/js/src/builtin/Intl.cpp @@ -99,16 +99,22 @@ Char16ToUChar(const char16_t* chars) } inline UChar* Char16ToUChar(char16_t* chars) { MOZ_CRASH("Char16ToUChar: Intl API disabled"); } +int32_t +u_strlen(const UChar* s) +{ + MOZ_CRASH("u_strlen: Intl API disabled"); +} + struct UEnumeration; int32_t uenum_count(UEnumeration* en, UErrorCode* status) { MOZ_CRASH("uenum_count: Intl API disabled"); } @@ -1513,20 +1519,22 @@ NewUNumberFormat(JSContext* cx, HandleOb return nullptr; if (equal(style, "currency")) { if (!GetProperty(cx, internals, internals, cx->names().currency, &value)) return nullptr; currency = value.toString(); MOZ_ASSERT(currency->length() == 3, "IsWellFormedCurrencyCode permits only length-3 strings"); - if (!stableChars.initTwoByte(cx, currency)) + if (!currency->ensureFlat(cx) || !stableChars.initTwoByte(cx, currency)) return nullptr; // uCurrency remains owned by stableChars. uCurrency = Char16ToUChar(stableChars.twoByteRange().begin().get()); + if (!uCurrency) + return nullptr; if (!GetProperty(cx, internals, internals, cx->names().currencyDisplay, &value)) return nullptr; JSAutoByteString currencyDisplay(cx, value.toString()); if (!currencyDisplay) return nullptr; if (equal(currencyDisplay, "code")) { uStyle = UNUM_CURRENCY_ISO; @@ -1621,31 +1629,29 @@ intl_FormatNumber(JSContext* cx, UNumber // FormatNumber doesn't consider -0.0 to be negative. if (IsNegativeZero(x)) x = 0.0; Vector<char16_t, INITIAL_CHAR_BUFFER_SIZE> chars(cx); if (!chars.resize(INITIAL_CHAR_BUFFER_SIZE)) return false; UErrorCode status = U_ZERO_ERROR; - int32_t size = unum_formatDouble(nf, x, Char16ToUChar(chars.begin()), INITIAL_CHAR_BUFFER_SIZE, - nullptr, &status); + int size = unum_formatDouble(nf, x, Char16ToUChar(chars.begin()), INITIAL_CHAR_BUFFER_SIZE, + nullptr, &status); if (status == U_BUFFER_OVERFLOW_ERROR) { - MOZ_ASSERT(size >= 0); if (!chars.resize(size)) return false; status = U_ZERO_ERROR; unum_formatDouble(nf, x, Char16ToUChar(chars.begin()), size, nullptr, &status); } if (U_FAILURE(status)) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); return false; } - MOZ_ASSERT(size >= 0); JSString* str = NewStringCopyN<CanGC>(cx, chars.begin(), size); if (!str) return false; result.setString(str); return true; } @@ -2037,17 +2043,17 @@ static js::HashNumber HashStringIgnoreCaseASCII(const Char* s, size_t length) { uint32_t hash = 0; for (size_t i = 0; i < length; i++) hash = mozilla::AddToHash(hash, ToUpperASCII(s[i])); return hash; } -js::SharedIntlData::TimeZoneHasher::Lookup::Lookup(JSLinearString* timeZone) +js::SharedIntlData::TimeZoneHasher::Lookup::Lookup(JSFlatString* timeZone) : isLatin1(timeZone->hasLatin1Chars()), length(timeZone->length()) { if (isLatin1) { latin1Chars = timeZone->latin1Chars(nogc); hash = HashStringIgnoreCaseASCII(latin1Chars, length); } else { twoByteChars = timeZone->twoByteChars(nogc); hash = HashStringIgnoreCaseASCII(twoByteChars, length); @@ -2203,39 +2209,39 @@ js::SharedIntlData::ensureTimeZones(JSCo bool js::SharedIntlData::validateTimeZoneName(JSContext* cx, HandleString timeZone, MutableHandleString result) { if (!ensureTimeZones(cx)) return false; - RootedLinearString timeZoneLinear(cx, timeZone->ensureLinear(cx)); - if (!timeZoneLinear) + Rooted<JSFlatString*> timeZoneFlat(cx, timeZone->ensureFlat(cx)); + if (!timeZoneFlat) return false; - TimeZoneHasher::Lookup lookup(timeZoneLinear); + TimeZoneHasher::Lookup lookup(timeZoneFlat); if (TimeZoneSet::Ptr p = availableTimeZones.lookup(lookup)) result.set(*p); return true; } bool js::SharedIntlData::tryCanonicalizeTimeZoneConsistentWithIANA(JSContext* cx, HandleString timeZone, MutableHandleString result) { if (!ensureTimeZones(cx)) return false; - RootedLinearString timeZoneLinear(cx, timeZone->ensureLinear(cx)); - if (!timeZoneLinear) + Rooted<JSFlatString*> timeZoneFlat(cx, timeZone->ensureFlat(cx)); + if (!timeZoneFlat) return false; - TimeZoneHasher::Lookup lookup(timeZoneLinear); + TimeZoneHasher::Lookup lookup(timeZoneFlat); MOZ_ASSERT(availableTimeZones.has(lookup), "Invalid time zone name"); if (TimeZoneMap::Ptr p = ianaLinksCanonicalizedDifferentlyByICU.lookup(lookup)) { // The effectively supported time zones aren't known at compile time, // when // 1. SpiderMonkey was compiled with "--with-system-icu". // 2. ICU's dynamic time zone data loading feature was used. // (ICU supports loading time zone files at runtime through the @@ -2429,52 +2435,54 @@ js::intl_patternForSkeleton(JSContext* c MOZ_ASSERT(args.length() == 2); MOZ_ASSERT(args[0].isString()); MOZ_ASSERT(args[1].isString()); JSAutoByteString locale(cx, args[0].toString()); if (!locale) return false; - AutoStableStringChars skeleton(cx); - if (!skeleton.initTwoByte(cx, args[1].toString())) + JSFlatString* skeletonFlat = args[1].toString()->ensureFlat(cx); + if (!skeletonFlat) return false; - mozilla::Range<const char16_t> skeletonChars = skeleton.twoByteRange(); + AutoStableStringChars stableChars(cx); + if (!stableChars.initTwoByte(cx, skeletonFlat)) + return false; + + mozilla::Range<const char16_t> skeletonChars = stableChars.twoByteRange(); + uint32_t skeletonLen = u_strlen(Char16ToUChar(skeletonChars.begin().get())); UErrorCode status = U_ZERO_ERROR; UDateTimePatternGenerator* gen = udatpg_open(icuLocale(locale.ptr()), &status); if (U_FAILURE(status)) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); return false; } ScopedICUObject<UDateTimePatternGenerator, udatpg_close> toClose(gen); - Vector<char16_t, INITIAL_CHAR_BUFFER_SIZE> chars(cx); - if (!chars.resize(INITIAL_CHAR_BUFFER_SIZE)) + int32_t size = udatpg_getBestPattern(gen, Char16ToUChar(skeletonChars.begin().get()), + skeletonLen, nullptr, 0, &status); + if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR) { + JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); return false; - - int32_t size = udatpg_getBestPattern(gen, Char16ToUChar(skeletonChars.begin().get()), - skeletonChars.length(), Char16ToUChar(chars.begin()), - INITIAL_CHAR_BUFFER_SIZE, &status); - if (status == U_BUFFER_OVERFLOW_ERROR) { - MOZ_ASSERT(size >= 0); - if (!chars.resize(size)) - return false; - status = U_ZERO_ERROR; - udatpg_getBestPattern(gen, Char16ToUChar(skeletonChars.begin().get()), - skeletonChars.length(), Char16ToUChar(chars.begin()), size, &status); } + ScopedJSFreePtr<UChar> pattern(cx->pod_malloc<UChar>(size + 1)); + if (!pattern) + return false; + pattern[size] = '\0'; + status = U_ZERO_ERROR; + udatpg_getBestPattern(gen, Char16ToUChar(skeletonChars.begin().get()), + skeletonLen, pattern, size, &status); if (U_FAILURE(status)) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); return false; } - MOZ_ASSERT(size >= 0); - JSString* str = NewStringCopyN<CanGC>(cx, chars.begin(), size); + RootedString str(cx, JS_NewUCStringCopyZ(cx, reinterpret_cast<char16_t*>(pattern.get()))); if (!str) return false; args.rval().setString(str); return true; } /** * Returns a new UDateFormat with the locale and date-time formatting options @@ -2497,36 +2505,39 @@ NewUDateFormat(JSContext* cx, HandleObje // We don't need to look at calendar and numberingSystem - they can only be // set via the Unicode locale extension and are therefore already set on // locale. if (!GetProperty(cx, internals, internals, cx->names().timeZone, &value)) return nullptr; - AutoStableStringChars timeZone(cx); - if (!timeZone.initTwoByte(cx, value.toString())) + AutoStableStringChars timeZoneChars(cx); + Rooted<JSFlatString*> timeZoneFlat(cx, value.toString()->ensureFlat(cx)); + if (!timeZoneFlat || !timeZoneChars.initTwoByte(cx, timeZoneFlat)) return nullptr; - mozilla::Range<const char16_t> timeZoneChars = timeZone.twoByteRange(); + const UChar* uTimeZone = Char16ToUChar(timeZoneChars.twoByteRange().begin().get()); + uint32_t uTimeZoneLength = u_strlen(uTimeZone); if (!GetProperty(cx, internals, internals, cx->names().pattern, &value)) return nullptr; - AutoStableStringChars pattern(cx); - if (!pattern.initTwoByte(cx, value.toString())) + AutoStableStringChars patternChars(cx); + Rooted<JSFlatString*> patternFlat(cx, value.toString()->ensureFlat(cx)); + if (!patternFlat || !patternChars.initTwoByte(cx, patternFlat)) return nullptr; - mozilla::Range<const char16_t> patternChars = pattern.twoByteRange(); + const UChar* uPattern = Char16ToUChar(patternChars.twoByteRange().begin().get()); + uint32_t uPatternLength = u_strlen(uPattern); UErrorCode status = U_ZERO_ERROR; UDateFormat* df = - udat_open(UDAT_PATTERN, UDAT_PATTERN, icuLocale(locale.ptr()), - Char16ToUChar(timeZoneChars.begin().get()), timeZoneChars.length(), - Char16ToUChar(patternChars.begin().get()), patternChars.length(), &status); + udat_open(UDAT_PATTERN, UDAT_PATTERN, icuLocale(locale.ptr()), uTimeZone, uTimeZoneLength, + uPattern, uPatternLength, &status); if (U_FAILURE(status)) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); return nullptr; } // ECMAScript requires the Gregorian calendar to be used from the beginning // of ECMAScript time. UCalendar* cal = const_cast<UCalendar*>(udat_getCalendar(df)); @@ -2544,31 +2555,29 @@ intl_FormatDateTime(JSContext* cx, UDate JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_DATE_NOT_FINITE); return false; } Vector<char16_t, INITIAL_CHAR_BUFFER_SIZE> chars(cx); if (!chars.resize(INITIAL_CHAR_BUFFER_SIZE)) return false; UErrorCode status = U_ZERO_ERROR; - int32_t size = udat_format(df, x, Char16ToUChar(chars.begin()), INITIAL_CHAR_BUFFER_SIZE, - nullptr, &status); + int size = udat_format(df, x, Char16ToUChar(chars.begin()), INITIAL_CHAR_BUFFER_SIZE, + nullptr, &status); if (status == U_BUFFER_OVERFLOW_ERROR) { - MOZ_ASSERT(size >= 0); if (!chars.resize(size)) return false; status = U_ZERO_ERROR; udat_format(df, x, Char16ToUChar(chars.begin()), size, nullptr, &status); } if (U_FAILURE(status)) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); return false; } - MOZ_ASSERT(size >= 0); JSString* str = NewStringCopyN<CanGC>(cx, chars.begin(), size); if (!str) return false; result.setString(str); return true; } @@ -2676,36 +2685,33 @@ intl_FormatToPartsDateTime(JSContext* cx UErrorCode status = U_ZERO_ERROR; UFieldPositionIterator* fpositer = ufieldpositer_open(&status); if (U_FAILURE(status)) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); return false; } auto closeFieldPosIter = MakeScopeExit([&]() { ufieldpositer_close(fpositer); }); - int32_t resultSize = + int resultSize = udat_formatForFields(df, x, Char16ToUChar(chars.begin()), INITIAL_CHAR_BUFFER_SIZE, fpositer, &status); if (status == U_BUFFER_OVERFLOW_ERROR) { - MOZ_ASSERT(resultSize >= 0); if (!chars.resize(resultSize)) return false; status = U_ZERO_ERROR; udat_formatForFields(df, x, Char16ToUChar(chars.begin()), resultSize, fpositer, &status); } if (U_FAILURE(status)) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); return false; } RootedArrayObject partsArray(cx, NewDenseEmptyArray(cx)); if (!partsArray) return false; - - MOZ_ASSERT(resultSize >= 0); if (resultSize == 0) { // An empty string contains no parts, so avoid extra work below. result.setObject(*partsArray); return true; } RootedString overallResult(cx, NewStringCopyN<CanGC>(cx, chars.begin(), resultSize)); if (!overallResult)
--- a/js/src/builtin/Intl.h +++ b/js/src/builtin/Intl.h @@ -77,17 +77,17 @@ class SharedIntlData const JS::Latin1Char* latin1Chars; const char16_t* twoByteChars; }; bool isLatin1; size_t length; JS::AutoCheckCannotGC nogc; HashNumber hash; - explicit Lookup(JSLinearString* timeZone); + explicit Lookup(JSFlatString* timeZone); }; static js::HashNumber hash(const Lookup& lookup) { return lookup.hash; } static bool match(TimeZoneName key, const Lookup& lookup); }; using TimeZoneSet = js::GCHashSet<TimeZoneName, TimeZoneHasher,