diff --git a/src/third_party/mozjs/extract/js/src/jsnum.cpp b/src/third_party/mozjs/extract/js/src/jsnum.cpp index a65af311611..0a78bcec39a 100644 --- a/src/third_party/mozjs/extract/js/src/jsnum.cpp +++ b/src/third_party/mozjs/extract/js/src/jsnum.cpp @@ -18,7 +18,6 @@ #include "mozilla/Utf8.h" #include -#include #include #include #ifdef HAVE_LOCALECONV @@ -46,6 +45,7 @@ #include "util/DoubleToString.h" #include "util/Memory.h" #include "util/StringBuilder.h" +#include "util/ToCharsCompat.h" // MONGODB MODIFICATION: MONGO_MOZJS_TO_CHARS #include "vm/BigIntType.h" #include "vm/GlobalObject.h" #include "vm/JSAtomUtils.h" // Atomize, AtomizeString @@ -791,8 +791,8 @@ JSLinearString* js::Int32ToStringWithHeap(JSContext* cx, int32_t si, char buffer[JSFatInlineString::MAX_LENGTH_LATIN1]; - auto result = std::to_chars(buffer, std::end(buffer), si, 10); - MOZ_ASSERT(result.ec == std::errc()); + // MONGODB MODIFICATION: use MONGO_MOZJS_TO_CHARS for macOS < 10.15 compatibility. + auto result = MONGO_MOZJS_TO_CHARS(buffer, std::end(buffer), si, 10); size_t length = result.ptr - buffer; const auto& latin1Chars = @@ -826,8 +826,8 @@ JSAtom* js::Int32ToAtom(JSContext* cx, int32_t si) { } Int32ToCStringBuf cbuf; - auto result = std::to_chars(cbuf.sbuf, std::end(cbuf.sbuf), si, 10); - MOZ_ASSERT(result.ec == std::errc()); + // MONGODB MODIFICATION: use MONGO_MOZJS_TO_CHARS for macOS < 10.15 compatibility. + auto result = MONGO_MOZJS_TO_CHARS(cbuf.sbuf, std::end(cbuf.sbuf), si, 10); Maybe indexValue; if (si >= 0) { @@ -847,8 +847,8 @@ JSAtom* js::Int32ToAtom(JSContext* cx, int32_t si) { frontend::TaggedParserAtomIndex js::Int32ToParserAtom( FrontendContext* fc, frontend::ParserAtomsTable& parserAtoms, int32_t si) { Int32ToCStringBuf cbuf; - auto result = std::to_chars(cbuf.sbuf, std::end(cbuf.sbuf), si, 10); - MOZ_ASSERT(result.ec == std::errc()); + // MONGODB MODIFICATION: use MONGO_MOZJS_TO_CHARS for macOS < 10.15 compatibility. + auto result = MONGO_MOZJS_TO_CHARS(cbuf.sbuf, std::end(cbuf.sbuf), si, 10); size_t length = result.ptr - cbuf.sbuf; return parserAtoms.internAscii(fc, cbuf.sbuf, length); @@ -873,8 +873,8 @@ static size_t Int32ToCString(char (&out)[Length], T i) { } // -1 to leave space for the terminating null-character. - auto result = std::to_chars(out, std::end(out) - 1, i, Base); - MOZ_ASSERT(result.ec == std::errc()); + // MONGODB MODIFICATION: use MONGO_MOZJS_TO_CHARS for macOS < 10.15 compatibility. + auto result = MONGO_MOZJS_TO_CHARS(out, std::end(out) - 1, i, Base); // Null-terminate the result. *result.ptr = '\0'; @@ -1642,25 +1642,9 @@ static JSLinearString* Int32ToStringWithBase(JSContext* cx, int32_t i, char buf[MaximumLength] = {}; - // Use explicit cases for base 10 and base 16 to make it more likely the - // compiler will generate optimized code for these two common bases. - std::to_chars_result result; - switch (base) { - case 10: { - result = std::to_chars(buf, std::end(buf), i, 10); - break; - } - case 16: { - result = std::to_chars(buf, std::end(buf), i, 16); - break; - } - default: { - MOZ_ASSERT(base >= 2 && base <= 36); - result = std::to_chars(buf, std::end(buf), i, base); - break; - } - } - MOZ_ASSERT(result.ec == std::errc()); + // MONGODB MODIFICATION: use MONGO_MOZJS_TO_CHARS for macOS < 10.15 compatibility. + MOZ_ASSERT(base >= 2 && base <= 36); + auto result = MONGO_MOZJS_TO_CHARS(buf, std::end(buf), i, base); size_t length = result.ptr - buf; MOZ_ASSERT(i < 0 || length > 2, "small static strings are handled above"); @@ -1790,8 +1774,8 @@ JSLinearString* js::IndexToString(JSContext* cx, uint32_t index) { char buffer[JSFatInlineString::MAX_LENGTH_LATIN1]; - auto result = std::to_chars(buffer, std::end(buffer), index, 10); - MOZ_ASSERT(result.ec == std::errc()); + // MONGODB MODIFICATION: use MONGO_MOZJS_TO_CHARS for macOS < 10.15 compatibility. + auto result = MONGO_MOZJS_TO_CHARS(buffer, std::end(buffer), index, 10); size_t length = result.ptr - buffer; const auto& latin1Chars = diff --git a/src/third_party/mozjs/extract/js/src/util/ToCharsCompat.h b/src/third_party/mozjs/extract/js/src/util/ToCharsCompat.h new file mode 100644 index 00000000000..491e286fc7f --- /dev/null +++ b/src/third_party/mozjs/extract/js/src/util/ToCharsCompat.h @@ -0,0 +1,112 @@ +/* -*- 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/. */ + +#ifndef util_ToCharsCompat_h +#define util_ToCharsCompat_h + +// MONGODB MODIFICATION: std::to_chars compatibility for macOS < 10.15. +// +// Apple's libc++ marks std::to_chars as unavailable when the deployment target +// is below macOS 10.15. On older backport branches (e.g. v7.0) that still +// target earlier macOS versions, this causes compile failures. This header +// provides a portable fallback that is selected at compile time. +// +// The fallback uses the same backfill-from-end algorithm that SpiderMonkey +// used prior to adopting std::to_chars (see the old Int32ToCStringWithBase +// in jsnum.cpp before ESR 140). + +#if defined(__APPLE__) && defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \ + __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 + +#include "mozilla/Assertions.h" + +#include +#include + +namespace js::detail { + +struct ToCharsResult { + char* ptr; +}; + +// Backfill-from-end integer-to-string conversion, matching the algorithm +// SpiderMonkey used before std::to_chars was adopted. Writes digits from +// the end of the buffer backwards, then returns a pointer past the last +// written character at the front. +template +ToCharsResult portable_to_chars(char* first, char* last, T value, int base) { + static_assert(std::is_integral_v, "integral types only"); + MOZ_ASSERT(base >= 2 && base <= 36); + MOZ_ASSERT(first < last); + + using Unsigned = std::make_unsigned_t; + bool negative = false; + Unsigned u; + if constexpr (std::is_signed_v) { + if (value < 0) { + negative = true; + u = static_cast(~static_cast(value) + 1u); + } else { + u = static_cast(value); + } + } else { + u = value; + } + + // Write digits backwards from the end of the buffer. + char* end = last; + char* cp = end; + do { + Unsigned newu = u / static_cast(base); + *--cp = "0123456789abcdefghijklmnopqrstuvwxyz" + [static_cast(u - newu * static_cast(base))]; + u = newu; + } while (u != 0); + + if (negative) { + *--cp = '-'; + } + + // Move the result to the front of the buffer. + size_t len = end - cp; + if (cp != first) { + for (size_t i = 0; i < len; i++) { + first[i] = cp[i]; + } + } + + return {first + len}; +} + +} // namespace js::detail + +#define MONGO_MOZJS_TO_CHARS(first, last, value, base) \ + js::detail::portable_to_chars(first, last, value, base) + +#else // macOS >= 10.15 or non-Apple platforms: use std::to_chars directly. + +#include "mozilla/Assertions.h" + +#include + +namespace js::detail { + +template +inline std::to_chars_result checked_to_chars(char* first, char* last, T value, + int base) { + auto r = std::to_chars(first, last, value, base); + MOZ_ASSERT(r.ec == std::errc()); + return r; +} + +} // namespace js::detail + +#define MONGO_MOZJS_TO_CHARS(first, last, value, base) \ + js::detail::checked_to_chars(first, last, value, base) + +#endif + +#endif /* util_ToCharsCompat_h */ diff --git a/src/third_party/mozjs/extract/js/src/vm/BigIntType.cpp b/src/third_party/mozjs/extract/js/src/vm/BigIntType.cpp index b12029be54b..3033e52ce63 100644 --- a/src/third_party/mozjs/extract/js/src/vm/BigIntType.cpp +++ b/src/third_party/mozjs/extract/js/src/vm/BigIntType.cpp @@ -92,7 +92,6 @@ #include "mozilla/Try.h" #include "mozilla/WrappingOperations.h" -#include #include #include #include @@ -108,6 +107,7 @@ #include "js/Utility.h" #include "util/CheckedArithmetic.h" #include "util/DifferentialTesting.h" +#include "util/ToCharsCompat.h" // MONGODB MODIFICATION: MONGO_MOZJS_TO_CHARS #include "vm/JSONPrinter.h" // js::JSONPrinter #include "vm/StaticStrings.h" @@ -1315,8 +1315,8 @@ JSLinearString* BigInt::toStringSingleDigit(JSContext* cx, Digit digit, *chars++ = '-'; } - auto result = std::to_chars(chars, std::end(resultChars), digit, radix); - MOZ_ASSERT(result.ec == std::errc()); + // MONGODB MODIFICATION: use MONGO_MOZJS_TO_CHARS for macOS < 10.15 compatibility. + auto result = MONGO_MOZJS_TO_CHARS(chars, std::end(resultChars), digit, radix); size_t length = result.ptr - resultChars; MOZ_ASSERT(length <= maxLength); diff --git a/src/third_party/mozjs/extract/js/src/vm/JSAtomUtils.cpp b/src/third_party/mozjs/extract/js/src/vm/JSAtomUtils.cpp index c4e049795c1..b8335245f1e 100644 --- a/src/third_party/mozjs/extract/js/src/vm/JSAtomUtils.cpp +++ b/src/third_party/mozjs/extract/js/src/vm/JSAtomUtils.cpp @@ -13,7 +13,6 @@ #include "mozilla/HashFunctions.h" // mozilla::HashStringKnownLength #include "mozilla/RangedPtr.h" -#include #include #include @@ -27,6 +26,7 @@ #include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_* #include "js/Symbol.h" #include "util/Text.h" +#include "util/ToCharsCompat.h" // MONGODB MODIFICATION: MONGO_MOZJS_TO_CHARS #include "vm/JSContext.h" #include "vm/JSObject.h" #include "vm/StaticStrings.h" @@ -903,8 +903,8 @@ bool js::IndexToIdSlow(JSContext* cx, uint32_t index, MutableHandleId idp) { char buf[UINT32_CHAR_BUFFER_LENGTH]; - auto result = std::to_chars(buf, buf + std::size(buf), index, 10); - MOZ_ASSERT(result.ec == std::errc()); + // MONGODB MODIFICATION: use MONGO_MOZJS_TO_CHARS for macOS < 10.15 compatibility. + auto result = MONGO_MOZJS_TO_CHARS(buf, buf + std::size(buf), index, 10); size_t length = result.ptr - buf; JSAtom* atom = Atomize(cx, buf, length); diff --git a/src/third_party/mozjs/extract/js/src/vm/TypedArrayObject.cpp b/src/third_party/mozjs/extract/js/src/vm/TypedArrayObject.cpp index b18b6f1547b..33232c01ca8 100644 --- a/src/third_party/mozjs/extract/js/src/vm/TypedArrayObject.cpp +++ b/src/third_party/mozjs/extract/js/src/vm/TypedArrayObject.cpp @@ -18,7 +18,6 @@ #include "mozilla/TextUtils.h" #include -#include #include #include #include @@ -48,6 +47,7 @@ #include "util/DifferentialTesting.h" #include "util/StringBuilder.h" #include "util/Text.h" +#include "util/ToCharsCompat.h" // MONGODB MODIFICATION: MONGO_MOZJS_TO_CHARS #include "util/WindowsWrapper.h" #include "vm/ArrayBufferObject.h" #include "vm/Float16.h" @@ -2016,9 +2016,9 @@ static bool TypedArrayJoinKernel(JSContext* cx, std::numeric_limits::is_signed; char str[MaximumLength] = {}; - auto result = std::to_chars(str, std::end(str), - static_cast(element), 10); - MOZ_ASSERT(result.ec == std::errc()); + // MONGODB MODIFICATION: use MONGO_MOZJS_TO_CHARS for macOS < 10.15 compatibility. + auto result = MONGO_MOZJS_TO_CHARS(str, std::end(str), + static_cast(element), 10); size_t strlen = result.ptr - str; if (!sb.append(str, strlen)) { diff --git a/src/third_party/mozjs/get-sources.sh b/src/third_party/mozjs/get-sources.sh index 26888fe79bd..2ccc53b0c88 100755 --- a/src/third_party/mozjs/get-sources.sh +++ b/src/third_party/mozjs/get-sources.sh @@ -10,7 +10,7 @@ NAME=spidermonkey VERSION="140.7.0esr" LIB_GIT_BRANCH=spidermonkey-esr140.7-cpp-only -LIB_GIT_REVISION=43ad77e05411b90dd589ec466494ece49cbf6044 +LIB_GIT_REVISION=692674d55f1c4acfae4316efab0f79cd67250341 LIB_GIT_REPO=git@github.com:mongodb-forks/spidermonkey.git # If a local spidermonkey repo exists, this is much faster than fetching from git: # LIB_GIT_REPO=/home/ubuntu/spidermonkey/.git