diff --git a/dom/media/webaudio/PannerNode.cpp b/dom/media/webaudio/PannerNode.cpp index a51c18e24c..775b6875a2 100644 --- a/dom/media/webaudio/PannerNode.cpp +++ b/dom/media/webaudio/PannerNode.cpp @@ -373,7 +373,9 @@ void PannerNode::DestroyMediaStream() float PannerNodeEngine::LinearGainFunction(double aDistance) { - return 1 - mRolloffFactor * (std::max(std::min(aDistance, mMaxDistance), mRefDistance) - mRefDistance) / (mMaxDistance - mRefDistance); + double clampedRollof = std::clamp(mRolloffFactor, 0.0, 1.0); + return AssertedCast( + 1.0 - clampedRollof * (std::max(std::min(aDistance, mMaxDistance), mRefDistance) - mRefDistance) / (mMaxDistance - mRefDistance)); } float diff --git a/dom/svg/DOMSVGPoint.h b/dom/svg/DOMSVGPoint.h index de27111083..389c456d40 100644 --- a/dom/svg/DOMSVGPoint.h +++ b/dom/svg/DOMSVGPoint.h @@ -81,7 +81,7 @@ public: { mPt.mX = aPt.x; mPt.mY = aPt.y; - NS_ASSERTION(IsFinite(mPt.mX) && IsFinite(mPt.mX), + NS_ASSERTION(IsFinite(mPt.mX) && IsFinite(mPt.mY), "DOMSVGPoint coords are not finite"); } diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp index 5dc4038be5..e45301c1d9 100644 --- a/dom/workers/ScriptLoader.cpp +++ b/dom/workers/ScriptLoader.cpp @@ -1246,9 +1246,8 @@ private: // We did inherit CSP in bug 1223647. If we do not already have a CSP, we // should get it from the HTTP headers on the worker script. - if (mWorkerPrivate->CSPEnabled() && - !mWorkerPrivate->GetCSP() && - CSPService::sCSPEnabled) { + if (CSPService::sCSPEnabled && + !mWorkerPrivate->GetCSP()) { rv = mWorkerPrivate->SetCSPFromHeaderValues(tCspHeaderValue, tCspROHeaderValue); NS_ENSURE_SUCCESS(rv, rv); diff --git a/gfx/2d/MacIOSurface.cpp b/gfx/2d/MacIOSurface.cpp index 66c583febd..dd1b6aae1d 100644 --- a/gfx/2d/MacIOSurface.cpp +++ b/gfx/2d/MacIOSurface.cpp @@ -21,7 +21,7 @@ using namespace mozilla; "/System/Library/Frameworks/ApplicationServices.framework/Frameworks/" \ "CoreGraphics.framework/CoreGraphics" #define COREVIDEO_FRAMEWORK_PATH \ - "/System/Library/Frameworks/ApplicationServices.framework/Frameworks/" \ + "/System/Library/Frameworks/" \ "CoreVideo.framework/CoreVideo" #define GET_CONST(const_name) \ diff --git a/js/src/builtin/Promise.cpp b/js/src/builtin/Promise.cpp index 7d4c232f2e..9660a758a1 100644 --- a/js/src/builtin/Promise.cpp +++ b/js/src/builtin/Promise.cpp @@ -85,7 +85,7 @@ enum RejectFunctionSlots { enum PromiseCombinatorElementFunctionSlots { PromiseCombinatorElementFunctionSlot_Data = 0, - PromiseCombinatorElementFunctionSlot_ElementIndex, + PromiseCombinatorElementFunctionSlot_ElementIndexOrResolveFunc, }; enum ReactionJobSlots { @@ -2351,7 +2351,8 @@ PerformPromiseThenWithoutSettleHandlers(JSContext* cx, Handle pr static JSFunction* NewPromiseCombinatorElementFunction( JSContext* cx, Native native, - Handle dataHolder, uint32_t index); + Handle dataHolder, uint32_t index, + Handle maybeResolveFunc); static bool PromiseAllResolveElementFunction(JSContext* cx, unsigned argc, Value* vp); @@ -2430,7 +2431,7 @@ js::GetWaitForAllPromise(JSContext* cx, const JS::AutoObjectVector& promises) // Steps j-o. JSFunction* resolveFunc = NewPromiseCombinatorElementFunction( - cx, PromiseAllResolveElementFunction, dataHolder, index); + cx, PromiseAllResolveElementFunction, dataHolder, index, UndefinedHandleValue); if (!resolveFunc) return nullptr; @@ -2888,7 +2889,7 @@ GetPromiseCombinatorElements(JSContext* cx, Handle static JSFunction* NewPromiseCombinatorElementFunction(JSContext* cx, Native native, Handle dataHolder, - uint32_t index) + uint32_t index, Handle maybeResolveFunc) { JSFunction* fn = NewNativeFunction(cx, native, 1, nullptr, gc::AllocKind::FUNCTION_EXTENDED, GenericObject); @@ -2898,8 +2899,13 @@ NewPromiseCombinatorElementFunction(JSContext* cx, Native native, fn->setExtendedSlot(PromiseCombinatorElementFunctionSlot_Data, ObjectValue(*dataHolder)); - fn->setExtendedSlot(PromiseCombinatorElementFunctionSlot_ElementIndex, - Int32Value(index)); + if (maybeResolveFunc.isObject()) { + fn->setExtendedSlot(PromiseCombinatorElementFunctionSlot_ElementIndexOrResolveFunc, + maybeResolveFunc); + } else { + fn->setExtendedSlot(PromiseCombinatorElementFunctionSlot_ElementIndexOrResolveFunc, + Int32Value(index)); + } return fn; } @@ -2917,6 +2923,13 @@ PromiseCombinatorElementFunctionAlreadyCalled(const CallArgs& args, // Step 1. JSFunction* fn = &args.callee().as(); + size_t indexOrResolveFuncSlot = PromiseCombinatorElementFunctionSlot_ElementIndexOrResolveFunc; + if (fn->getExtendedSlot(indexOrResolveFuncSlot).isObject()) { + Value slotVal = fn->getExtendedSlot(indexOrResolveFuncSlot); + fn = &slotVal.toObject().as(); + } + MOZ_RELEASE_ASSERT(fn->getExtendedSlot(indexOrResolveFuncSlot).isInt32()); + // Step 2. const Value& dataVal = fn->getExtendedSlot(PromiseCombinatorElementFunctionSlot_Data); @@ -2936,9 +2949,7 @@ PromiseCombinatorElementFunctionAlreadyCalled(const CallArgs& args, UndefinedValue()); // Step 5. - int32_t idx = - fn->getExtendedSlot(PromiseCombinatorElementFunctionSlot_ElementIndex) - .toInt32(); + int32_t idx = fn->getExtendedSlot(indexOrResolveFuncSlot).toInt32(); MOZ_ASSERT(idx >= 0); *index = uint32_t(idx); @@ -2988,7 +2999,7 @@ PerformPromiseAll(JSContext *cx, PromiseForOfIterator& iterator, HandleObject C, // Steps 8.j-p. JSFunction* resolveFunc = NewPromiseCombinatorElementFunction(cx, - PromiseAllResolveElementFunction, dataHolder, index); + PromiseAllResolveElementFunction, dataHolder, index, UndefinedHandleValue); if (!resolveFunc) return false; @@ -3187,7 +3198,7 @@ static MOZ_MUST_USE bool PerformPromiseAllSettled( // Steps 8.j-q. JSFunction* resolveFunc = NewPromiseCombinatorElementFunction( - cx, PromiseAllSettledResolveElementFunction, dataHolder, index); + cx, PromiseAllSettledResolveElementFunction, dataHolder, index, UndefinedHandleValue); if (!resolveFunc) { return false; } @@ -3195,7 +3206,7 @@ static MOZ_MUST_USE bool PerformPromiseAllSettled( // Steps 8.r-x. JSFunction* rejectFunc = NewPromiseCombinatorElementFunction( - cx, PromiseAllSettledRejectElementFunction, dataHolder, index); + cx, PromiseAllSettledRejectElementFunction, dataHolder, index, resolveFunVal); if (!rejectFunc) { return false; } @@ -3391,7 +3402,7 @@ PerformPromiseAny(JSContext* cx, PromiseForOfIterator& iterator, HandleObject C, // Steps 8.j-p. JSFunction* rejectFunc = NewPromiseCombinatorElementFunction( - cx, PromiseAnyRejectElementFunction, dataHolder, index); + cx, PromiseAnyRejectElementFunction, dataHolder, index, UndefinedHandleValue); if (!rejectFunc) { return false; } diff --git a/js/src/jit/IonAnalysis.cpp b/js/src/jit/IonAnalysis.cpp index aa8f8164b5..303b2d1568 100644 --- a/js/src/jit/IonAnalysis.cpp +++ b/js/src/jit/IonAnalysis.cpp @@ -2892,6 +2892,12 @@ jit::ExtractLinearSum(MDefinition* ins, MathSpace space) return SimpleLinearSum(ins, 0); MOZ_ASSERT(space == MathSpace::Modulo || space == MathSpace::Infinite); + // We don't support modulo math space in ExtractLinearSum, because it + // doesn't work well in some compilation environments. + if (space == MathSpace::Modulo) { + return SimpleLinearSum(ins, 0); + } + MDefinition* lhs = ins->getOperand(0); MDefinition* rhs = ins->getOperand(1); if (lhs->type() != MIRType::Int32 || rhs->type() != MIRType::Int32) diff --git a/media/webrtc/trunk/build/mac/find_sdk_uxp.py b/media/webrtc/trunk/build/mac/find_sdk_uxp.py index a68e165f1a..4d0cac51a6 100644 --- a/media/webrtc/trunk/build/mac/find_sdk_uxp.py +++ b/media/webrtc/trunk/build/mac/find_sdk_uxp.py @@ -21,8 +21,9 @@ if sys.platform == 'darwin': KNOWN_SDK_VERSIONS = ["10.7", "10.8", "10.9", "10.10", "10.11" "10.12", "10.13", "10.14", "10.15", "10.16", - "11.0", "11.1", "11.2", "11.3", - "12.0"] + "11.0", "11.1", "11.2", "11.3", "12.0", "12.1", "12.3", + "13.0", "13.1", "13.2", "14.0", "14.2", "14.4", "14.5", + "15.0", "15.1", "15.2", "15.4"] REGEX = "^MacOSX(\d+\.\d+)\.sdk$" SDK_VERSION = re.findall(REGEX, os.path.basename(SDK_PATH)) diff --git a/memory/mozalloc/mozalloc.cpp b/memory/mozalloc/mozalloc.cpp index 21d8e8666e..57976ac953 100644 --- a/memory/mozalloc/mozalloc.cpp +++ b/memory/mozalloc/mozalloc.cpp @@ -3,6 +3,8 @@ * 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/. */ +#include // These need to be included before overriding +#include // with clang on 32-bit ARM Linux -dbsoft #include // for size_t // Building with USE_STATIC_LIBS = True sets -MT instead of -MD. -MT sets _MT, diff --git a/mfbt/Casting.h b/mfbt/Casting.h index 36de1188e9..518208ebe1 100644 --- a/mfbt/Casting.h +++ b/mfbt/Casting.h @@ -11,7 +11,8 @@ #include "mozilla/Assertions.h" #include "mozilla/TypeTraits.h" -#include +#include +#include namespace mozilla { @@ -62,190 +63,141 @@ BitwiseCast(const From aFrom) namespace detail { -enum ToSignedness { ToIsSigned, ToIsUnsigned }; -enum FromSignedness { FromIsSigned, FromIsUnsigned }; +template +constexpr int64_t safe_integer() { + static_assert(std::is_floating_point_v); + return std::pow(2, std::numeric_limits::digits); +} -template::value ? FromIsSigned : FromIsUnsigned, - ToSignedness = IsSigned::value ? ToIsSigned : ToIsUnsigned> -struct BoundsCheckImpl; +template +constexpr uint64_t safe_integer_unsigned() { + static_assert(std::is_floating_point_v); + return std::pow(2, std::numeric_limits::digits); +} -// Implicit conversions on operands to binary operations make this all a bit -// hard to verify. Attempt to ease the pain below by *only* comparing values -// that are obviously the same type (and will undergo no further conversions), -// even when it's not strictly necessary, for explicitness. +#ifdef __GNUC__ +// This is working around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81676, +// fixed in gcc-10 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" +#endif -enum UUComparison { FromIsBigger, FromIsNotBigger }; +template +bool IsInBounds(In aIn) { + constexpr bool inSigned = std::is_signed_v; + constexpr bool outSigned = std::is_signed_v; + constexpr bool bothSigned = inSigned && outSigned; + constexpr bool bothUnsigned = !inSigned && !outSigned; + constexpr bool inFloat = std::is_floating_point_v; + constexpr bool outFloat = std::is_floating_point_v; + constexpr bool bothFloat = inFloat && outFloat; + constexpr bool noneFloat = !inFloat && !outFloat; + constexpr Out outMax = std::numeric_limits::max(); + constexpr Out outMin = std::numeric_limits::lowest(); -// Unsigned-to-unsigned range check + // This selects the widest of two types, and is used to cast throughout. + using select_widest = std::conditional_t<(sizeof(In) > sizeof(Out)), In, Out>; -template sizeof(To)) - ? FromIsBigger - : FromIsNotBigger> -struct UnsignedUnsignedCheck; - -template -struct UnsignedUnsignedCheck -{ -public: - static bool checkBounds(const From aFrom) - { - return aFrom <= From(To(-1)); - } -}; - -template -struct UnsignedUnsignedCheck -{ -public: - static bool checkBounds(const From aFrom) - { - return true; - } -}; - -template -struct BoundsCheckImpl -{ -public: - static bool checkBounds(const From aFrom) - { - return UnsignedUnsignedCheck::checkBounds(aFrom); - } -}; - -// Signed-to-unsigned range check - -template -struct BoundsCheckImpl -{ -public: - static bool checkBounds(const From aFrom) - { - if (aFrom < 0) { + if constexpr (bothFloat) { + if (aIn > select_widest(outMax) || aIn < select_widest(outMin)) { return false; } - if (sizeof(To) >= sizeof(From)) { - return true; + } + // Normal casting applies, the floating point number is floored. + if constexpr (inFloat && !outFloat) { + static_assert(sizeof(aIn) <= sizeof(int64_t)); + // Check if the input floating point is larger than the output bounds. This + // catches situations where the input is a float larger than the max of the + // output type. + if (aIn < static_cast(outMin) || + aIn > static_cast(outMax)) { + return false; } - return aFrom <= From(To(-1)); - } -}; - -// Unsigned-to-signed range check - -enum USComparison { FromIsSmaller, FromIsNotSmaller }; - -template -struct UnsignedSignedCheck; - -template -struct UnsignedSignedCheck -{ -public: - static bool checkBounds(const From aFrom) - { - return true; - } -}; - -template -struct UnsignedSignedCheck -{ -public: - static bool checkBounds(const From aFrom) - { - const To MaxValue = To((1ULL << (CHAR_BIT * sizeof(To) - 1)) - 1); - return aFrom <= From(MaxValue); - } -}; - -template -struct BoundsCheckImpl -{ -public: - static bool checkBounds(const From aFrom) - { - return UnsignedSignedCheck::checkBounds(aFrom); - } -}; - -// Signed-to-signed range check - -template -struct BoundsCheckImpl -{ -public: - static bool checkBounds(const From aFrom) - { - if (sizeof(From) <= sizeof(To)) { - return true; + // At this point we know that the input can be converted to an integer. + // Check if it's larger than the bounds of the target integer. + if (outSigned) { + int64_t asInteger = static_cast(aIn); + if (asInteger < outMin || asInteger > outMax) { + return false; + } + } else { + uint64_t asInteger = static_cast(aIn); + if (asInteger > outMax) { + return false; + } } - const To MaxValue = To((1ULL << (CHAR_BIT * sizeof(To) - 1)) - 1); - const To MinValue = -MaxValue - To(1); - return From(MinValue) <= aFrom && - From(aFrom) <= From(MaxValue); } -}; - -template::value && - IsIntegral::value> -class BoundsChecker; - -template -class BoundsChecker -{ -public: - static bool checkBounds(const From aFrom) { return true; } -}; - -template -class BoundsChecker -{ -public: - static bool checkBounds(const From aFrom) - { - return BoundsCheckImpl::checkBounds(aFrom); + // Checks if the integer is representable exactly as a floating point value of + // a specific width. + if constexpr (!inFloat && outFloat) { + if constexpr (inSigned) { + if (aIn < -safe_integer() || aIn > safe_integer()) { + return false; + } + } else { + if (aIn >= safe_integer_unsigned()) { + return false; + } + } } -}; - -template -inline bool -IsInBounds(const From aFrom) -{ - return BoundsChecker::checkBounds(aFrom); + if constexpr (noneFloat) { + if constexpr (bothUnsigned) { + if (aIn > select_widest(outMax)) { + return false; + } + } + if constexpr (bothSigned) { + if (aIn > select_widest(outMax) || aIn < select_widest(outMin)) { + return false; + } + } + if constexpr (inSigned && !outSigned) { + if (aIn < 0 || std::make_unsigned_t(aIn) > outMax) { + return false; + } + } + if constexpr (!inSigned && outSigned) { + if (aIn > select_widest(outMax)) { + return false; + } + } + } + return true; } +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + } // namespace detail /** - * Cast a value of integral type |From| to a value of integral type |To|, - * asserting that the cast will be a safe cast per C++ (that is, that |to| is in - * the range of values permitted for the type |From|). + * Cast a value of type |From| to a value of type |To|, asserting that the cast + * will be a safe cast per C++ (that is, that |to| is in the range of values + * permitted for the type |From|). + * In particular, this will fail if a integer cann */ template inline To AssertedCast(const From aFrom) { + static_assert(std::is_arithmetic_v && std::is_arithmetic_v); MOZ_ASSERT((detail::IsInBounds(aFrom))); return static_cast(aFrom); } /** - * Cast a value of integral type |From| to a value of integral type |To|, - * release asserting that the cast will be a safe cast per C++ (that is, that - * |to| is in the range of values permitted for the type |From|). + * Cast a value of numeric type |From| to a value of numeric type |To|, release + * asserting that the cast will be a safe cast per C++ (that is, that |to| is in + * the range of values permitted for the type |From|). + * In particular, this will fail if a integer cannot be represented exactly as a + * floating point value, because it's too large. */ template inline To ReleaseAssertedCast(const From aFrom) { + static_assert(std::is_arithmetic_v && std::is_arithmetic_v); MOZ_RELEASE_ASSERT((detail::IsInBounds(aFrom))); return static_cast(aFrom); } diff --git a/mfbt/tests/TestCasting.cpp b/mfbt/tests/TestCasting.cpp index 0b6e4a5bd3..7d8231ad04 100644 --- a/mfbt/tests/TestCasting.cpp +++ b/mfbt/tests/TestCasting.cpp @@ -4,12 +4,20 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/Casting.h" +#include "mozilla/ThreadSafety.h" +#include "mozilla/TypeTraits.h" #include +#include +#include +using mozilla::AssertedCast; using mozilla::BitwiseCast; using mozilla::detail::IsInBounds; +static const uint8_t floatMantissaBitsPlusOne = 24; +static const uint8_t doubleMantissaBitsPlusOne = 53; + template struct UintUlongBitwiseCast; @@ -98,6 +106,153 @@ TestToSmallerSize() MOZ_RELEASE_ASSERT((!IsInBounds(int64_t(UINT32_MAX) + 1))); } +template +void checkBoundariesFloating(In aEpsilon = {}, Out aIntegerOffset = {}) { + // Check the max value of the input float can't be represented as an integer. + // This is true for all floating point and integer width. + MOZ_RELEASE_ASSERT((!IsInBounds(std::numeric_limits::max()))); + // Check that the max value of the integer, as a float, minus an offset that + // depends on the magnitude, can be represented as an integer. + MOZ_RELEASE_ASSERT((IsInBounds( + static_cast(std::numeric_limits::max() - aIntegerOffset)))); + // Check that the max value of the integer, plus a number that depends on the + // magnitude of the number, can't be represented as this integer (because it + // becomes too big). + MOZ_RELEASE_ASSERT((!IsInBounds( + aEpsilon + static_cast(std::numeric_limits::max())))); + if constexpr (std::is_signed_v) { + // Same for negative numbers. + MOZ_RELEASE_ASSERT( + (!IsInBounds(std::numeric_limits::lowest()))); + MOZ_RELEASE_ASSERT((IsInBounds( + static_cast(std::numeric_limits::lowest())))); + MOZ_RELEASE_ASSERT((!IsInBounds( + static_cast(std::numeric_limits::lowest()) - aEpsilon))); + } else { + // Check for negative floats and unsigned integer types. + MOZ_RELEASE_ASSERT((!IsInBounds(static_cast(-1)))); + } +} + +void TestFloatConversion() { + MOZ_RELEASE_ASSERT((!IsInBounds(UINT64_MAX))); + MOZ_RELEASE_ASSERT((!IsInBounds(UINT32_MAX))); + MOZ_RELEASE_ASSERT((IsInBounds(UINT16_MAX))); + MOZ_RELEASE_ASSERT((IsInBounds(UINT8_MAX))); + + MOZ_RELEASE_ASSERT((!IsInBounds(INT64_MAX))); + MOZ_RELEASE_ASSERT((!IsInBounds(INT64_MIN))); + MOZ_RELEASE_ASSERT((!IsInBounds(INT32_MAX))); + MOZ_RELEASE_ASSERT((!IsInBounds(INT32_MIN))); + MOZ_RELEASE_ASSERT((IsInBounds(INT16_MAX))); + MOZ_RELEASE_ASSERT((IsInBounds(INT16_MIN))); + MOZ_RELEASE_ASSERT((IsInBounds(INT8_MAX))); + MOZ_RELEASE_ASSERT((IsInBounds(INT8_MIN))); + + MOZ_RELEASE_ASSERT((!IsInBounds(UINT64_MAX))); + MOZ_RELEASE_ASSERT((IsInBounds(UINT32_MAX))); + MOZ_RELEASE_ASSERT((IsInBounds(UINT16_MAX))); + MOZ_RELEASE_ASSERT((IsInBounds(UINT8_MAX))); + + MOZ_RELEASE_ASSERT((!IsInBounds(INT64_MAX))); + MOZ_RELEASE_ASSERT((!IsInBounds(INT64_MIN))); + MOZ_RELEASE_ASSERT((IsInBounds(INT32_MAX))); + MOZ_RELEASE_ASSERT((IsInBounds(INT32_MIN))); + MOZ_RELEASE_ASSERT((IsInBounds(INT16_MAX))); + MOZ_RELEASE_ASSERT((IsInBounds(INT16_MIN))); + MOZ_RELEASE_ASSERT((IsInBounds(INT8_MAX))); + MOZ_RELEASE_ASSERT((IsInBounds(INT8_MIN))); + + // Floor check + MOZ_RELEASE_ASSERT((IsInBounds(4.3))); + MOZ_RELEASE_ASSERT((AssertedCast(4.3f) == 4u)); + MOZ_RELEASE_ASSERT((IsInBounds(4.3))); + MOZ_RELEASE_ASSERT((AssertedCast(4.3f) == 4u)); + MOZ_RELEASE_ASSERT((IsInBounds(4.3))); + MOZ_RELEASE_ASSERT((AssertedCast(4.3f) == 4u)); + MOZ_RELEASE_ASSERT((IsInBounds(4.3))); + MOZ_RELEASE_ASSERT((AssertedCast(4.3f) == 4u)); + + MOZ_RELEASE_ASSERT((IsInBounds(4.3))); + MOZ_RELEASE_ASSERT((AssertedCast(4.3f) == 4u)); + MOZ_RELEASE_ASSERT((IsInBounds(4.3))); + MOZ_RELEASE_ASSERT((AssertedCast(4.3f) == 4u)); + MOZ_RELEASE_ASSERT((IsInBounds(4.3))); + MOZ_RELEASE_ASSERT((AssertedCast(4.3f) == 4u)); + MOZ_RELEASE_ASSERT((IsInBounds(4.3))); + MOZ_RELEASE_ASSERT((AssertedCast(4.3f) == 4u)); + + MOZ_RELEASE_ASSERT((IsInBounds(-4.3))); + MOZ_RELEASE_ASSERT((AssertedCast(-4.3f) == -4)); + MOZ_RELEASE_ASSERT((IsInBounds(-4.3))); + MOZ_RELEASE_ASSERT((AssertedCast(-4.3f) == -4)); + MOZ_RELEASE_ASSERT((IsInBounds(-4.3))); + MOZ_RELEASE_ASSERT((AssertedCast(-4.3f) == -4)); + MOZ_RELEASE_ASSERT((IsInBounds(-4.3))); + MOZ_RELEASE_ASSERT((AssertedCast(-4.3f) == -4)); + + // Bound check for float to unsigned integer conversion. The parameters are + // espilons and offsets allowing to check boundaries, that depend on the + // magnitude of the numbers. + checkBoundariesFloating(2049.); + checkBoundariesFloating(1.); + checkBoundariesFloating(1.); + checkBoundariesFloating(1.); + // Large number because of the lack of precision of floats at this magnitude + checkBoundariesFloating(1.1e12f); + checkBoundariesFloating(1.f, 128u); + checkBoundariesFloating(1.f); + checkBoundariesFloating(1.f); + + checkBoundariesFloating(1025.); + checkBoundariesFloating(1.); + checkBoundariesFloating(1.); + checkBoundariesFloating(1.); + // Large number because of the lack of precision of floats at this magnitude + checkBoundariesFloating(1.1e12f); + checkBoundariesFloating(256.f, 64u); + checkBoundariesFloating(1.f); + checkBoundariesFloating(1.f); + + // Integer to floating point, boundary cases + MOZ_RELEASE_ASSERT(!(IsInBounds( + int64_t(std::pow(2, floatMantissaBitsPlusOne)) + 1))); + MOZ_RELEASE_ASSERT((IsInBounds( + int64_t(std::pow(2, floatMantissaBitsPlusOne))))); + MOZ_RELEASE_ASSERT((IsInBounds( + int64_t(std::pow(2, floatMantissaBitsPlusOne)) - 1))); + + MOZ_RELEASE_ASSERT(!(IsInBounds( + int64_t(-std::pow(2, floatMantissaBitsPlusOne)) - 1))); + MOZ_RELEASE_ASSERT((IsInBounds( + int64_t(-std::pow(2, floatMantissaBitsPlusOne))))); + MOZ_RELEASE_ASSERT((IsInBounds( + int64_t(-std::pow(2, floatMantissaBitsPlusOne)) + 1))); + + MOZ_RELEASE_ASSERT(!(IsInBounds( + uint64_t(std::pow(2, doubleMantissaBitsPlusOne)) + 1))); + MOZ_RELEASE_ASSERT((IsInBounds( + uint64_t(std::pow(2, doubleMantissaBitsPlusOne))))); + MOZ_RELEASE_ASSERT((IsInBounds( + uint64_t(std::pow(2, doubleMantissaBitsPlusOne)) - 1))); + + MOZ_RELEASE_ASSERT(!(IsInBounds( + int64_t(-std::pow(2, doubleMantissaBitsPlusOne)) - 1))); + MOZ_RELEASE_ASSERT((IsInBounds( + int64_t(-std::pow(2, doubleMantissaBitsPlusOne))))); + MOZ_RELEASE_ASSERT((IsInBounds( + int64_t(-std::pow(2, doubleMantissaBitsPlusOne)) + 1))); + + MOZ_RELEASE_ASSERT(!(IsInBounds(UINT64_MAX))); + MOZ_RELEASE_ASSERT(!(IsInBounds(INT64_MAX))); + MOZ_RELEASE_ASSERT(!(IsInBounds(INT64_MIN))); + + MOZ_RELEASE_ASSERT( + !(IsInBounds(std::numeric_limits::max()))); + MOZ_RELEASE_ASSERT( + !(IsInBounds(-std::numeric_limits::max()))); +} + int main() { @@ -106,6 +261,7 @@ main() TestSameSize(); TestToBiggerSize(); TestToSmallerSize(); + TestFloatConversion(); return 0; } diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 17e105c7a6..350ddbcd8d 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -2737,18 +2737,6 @@ pref("layout.frame_rate", -1); pref("layout.display-list.dump", false); pref("layout.display-list.dump-content", false); -// pref to control precision of the frame rate timer. When true, -// we use a "precise" timer, which means each notification fires -// Nms after the start of the last notification. That means if the -// processing of the notification is slow, the timer can fire immediately -// after we've just finished processing the last notification, which might -// lead to starvation problems. -// When false, we use a "slack" timer which fires Nms after the *end* -// of the last notification. This can give less tight frame rates -// but provides more time for other operations when the browser is -// heavily loaded. -pref("layout.frame_rate.precise", false); - // pref to control whether layout warnings that are hit quite often are enabled pref("layout.spammy_warnings.enabled", false); diff --git a/toolkit/components/protobuf/moz.build b/toolkit/components/protobuf/moz.build index 41c6f3d75e..633bb76585 100644 --- a/toolkit/components/protobuf/moz.build +++ b/toolkit/components/protobuf/moz.build @@ -130,6 +130,11 @@ elif CONFIG['_MSC_VER']: '-wd4099', # mismatched class/struct tags ] +if CONFIG['_MSC_VER']: + CXXFLAGS += [ + '-GR', # protobuf uses dynamic_cast on polymorphic types + ] + if CONFIG['MOZ_USE_PTHREADS']: DEFINES['HAVE_PTHREAD'] = True