Bug 858131 - rewrite FloatingPoint.h to be C++-only instead of C-compatible C++; r+original-author=Waldo

This commit is contained in:
Nathan Froyd 2013-05-01 16:55:13 -04:00
parent 0006769208
commit eba34f22d7
57 changed files with 344 additions and 319 deletions

View File

@ -1187,7 +1187,7 @@ HTMLInputElement::ConvertStringToNumber(nsAString& aValue,
} }
double date = JS::MakeDate(year, month - 1, day); double date = JS::MakeDate(year, month - 1, day);
if (MOZ_DOUBLE_IS_NaN(date)) { if (IsNaN(date)) {
return false; return false;
} }
@ -1361,9 +1361,7 @@ HTMLInputElement::ConvertNumberToString(Decimal aValue,
double month = JS::MonthFromTime(aValue.toDouble()); double month = JS::MonthFromTime(aValue.toDouble());
double day = JS::DayFromTime(aValue.toDouble()); double day = JS::DayFromTime(aValue.toDouble());
if (MOZ_DOUBLE_IS_NaN(year) || if (IsNaN(year) || IsNaN(month) || IsNaN(day)) {
MOZ_DOUBLE_IS_NaN(month) ||
MOZ_DOUBLE_IS_NaN(day)) {
return false; return false;
} }
@ -1474,7 +1472,7 @@ HTMLInputElement::SetValueAsNumber(double aValueAsNumber, ErrorResult& aRv)
{ {
// TODO: return TypeError when HTMLInputElement is converted to WebIDL, see // TODO: return TypeError when HTMLInputElement is converted to WebIDL, see
// bug 825197. // bug 825197.
if (MOZ_DOUBLE_IS_INFINITE(aValueAsNumber)) { if (IsInfinite(aValueAsNumber)) {
aRv.Throw(NS_ERROR_INVALID_ARG); aRv.Throw(NS_ERROR_INVALID_ARG);
return; return;
} }
@ -3443,7 +3441,7 @@ HTMLInputElement::SanitizeValue(nsAString& aValue)
{ {
nsresult ec; nsresult ec;
double val = PromiseFlatString(aValue).ToDouble(&ec); double val = PromiseFlatString(aValue).ToDouble(&ec);
if (NS_FAILED(ec) || !MOZ_DOUBLE_IS_FINITE(val)) { if (NS_FAILED(ec) || !IsFinite(val)) {
aValue.Truncate(); aValue.Truncate();
} }
} }

View File

@ -581,7 +581,7 @@ public:
double ValueAsNumber() const double ValueAsNumber() const
{ {
return DoesValueAsNumberApply() ? GetValueAsDecimal().toDouble() return DoesValueAsNumberApply() ? GetValueAsDecimal().toDouble()
: MOZ_DOUBLE_NaN(); : UnspecifiedNaN();
} }
void SetValueAsNumber(double aValue, ErrorResult& aRv); void SetValueAsNumber(double aValue, ErrorResult& aRv);

View File

@ -130,7 +130,7 @@ struct AudioTimelineEvent {
private: private:
static bool IsValid(double value) static bool IsValid(double value)
{ {
return MOZ_DOUBLE_IS_FINITE(value); return mozilla::IsFinite(value);
} }
}; };

View File

@ -1219,9 +1219,9 @@ void MediaDecoder::DurationChanged()
void MediaDecoder::SetDuration(double aDuration) void MediaDecoder::SetDuration(double aDuration)
{ {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
if (MOZ_DOUBLE_IS_INFINITE(aDuration)) { if (mozilla::IsInfinite(aDuration)) {
SetInfinite(true); SetInfinite(true);
} else if (MOZ_DOUBLE_IS_NaN(aDuration)) { } else if (IsNaN(aDuration)) {
mDuration = -1; mDuration = -1;
SetInfinite(true); SetInfinite(true);
} else { } else {

View File

@ -90,7 +90,7 @@ struct WebAudioUtils {
static void FixNaN(double& aDouble) static void FixNaN(double& aDouble)
{ {
if (MOZ_DOUBLE_IS_NaN(aDouble) || MOZ_DOUBLE_IS_INFINITE(aDouble)) { if (IsNaN(aDouble) || IsInfinite(aDouble)) {
aDouble = 0.0; aDouble = 0.0;
} }
} }

View File

@ -37,6 +37,8 @@
using namespace std; using namespace std;
using mozilla::dom::WebAudioUtils; using mozilla::dom::WebAudioUtils;
using mozilla::IsInfinite;
using mozilla::IsNaN;
namespace WebCore { namespace WebCore {
@ -285,9 +287,9 @@ void DynamicsCompressorKernel::process(float* sourceChannels[],
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Fix gremlins. // Fix gremlins.
if (MOZ_DOUBLE_IS_NaN(m_detectorAverage)) if (IsNaN(m_detectorAverage))
m_detectorAverage = 1; m_detectorAverage = 1;
if (MOZ_DOUBLE_IS_INFINITE(m_detectorAverage)) if (IsInfinite(m_detectorAverage))
m_detectorAverage = 1; m_detectorAverage = 1;
float desiredGain = m_detectorAverage; float desiredGain = m_detectorAverage;
@ -313,9 +315,9 @@ void DynamicsCompressorKernel::process(float* sourceChannels[],
m_maxAttackCompressionDiffDb = -1; m_maxAttackCompressionDiffDb = -1;
// Fix gremlins. // Fix gremlins.
if (MOZ_DOUBLE_IS_NaN(compressionDiffDb)) if (IsNaN(compressionDiffDb))
compressionDiffDb = -1; compressionDiffDb = -1;
if (MOZ_DOUBLE_IS_INFINITE(compressionDiffDb)) if (IsInfinite(compressionDiffDb))
compressionDiffDb = -1; compressionDiffDb = -1;
// Adaptive release - higher compression (lower compressionDiffDb) releases faster. // Adaptive release - higher compression (lower compressionDiffDb) releases faster.
@ -341,9 +343,9 @@ void DynamicsCompressorKernel::process(float* sourceChannels[],
// Attack mode - compressionDiffDb should be positive dB // Attack mode - compressionDiffDb should be positive dB
// Fix gremlins. // Fix gremlins.
if (MOZ_DOUBLE_IS_NaN(compressionDiffDb)) if (IsNaN(compressionDiffDb))
compressionDiffDb = 1; compressionDiffDb = 1;
if (MOZ_DOUBLE_IS_INFINITE(compressionDiffDb)) if (IsInfinite(compressionDiffDb))
compressionDiffDb = 1; compressionDiffDb = 1;
// As long as we're still in attack mode, use a rate based off // As long as we're still in attack mode, use a rate based off
@ -409,9 +411,9 @@ void DynamicsCompressorKernel::process(float* sourceChannels[],
detectorAverage = min(1.0f, detectorAverage); detectorAverage = min(1.0f, detectorAverage);
// Fix gremlins. // Fix gremlins.
if (MOZ_DOUBLE_IS_NaN(detectorAverage)) if (IsNaN(detectorAverage))
detectorAverage = 1; detectorAverage = 1;
if (MOZ_DOUBLE_IS_INFINITE(detectorAverage)) if (IsInfinite(detectorAverage))
detectorAverage = 1; detectorAverage = 1;
// Exponential approach to desired gain. // Exponential approach to desired gain.

View File

@ -105,7 +105,7 @@ public:
{ {
if (mState == eIllegal || mBuffer.IsEmpty() || if (mState == eIllegal || mBuffer.IsEmpty() ||
(mBuffer.Length() == 1 && mBuffer[0] == '.')) { (mBuffer.Length() == 1 && mBuffer[0] == '.')) {
return MOZ_DOUBLE_NaN(); return mozilla::UnspecifiedNaN();
} }
return mSign*PR_strtod(mBuffer.get(), 0); return mSign*PR_strtod(mBuffer.get(), 0);
} }
@ -142,11 +142,11 @@ void txDouble::toString(double aValue, nsAString& aDest)
// check for special cases // check for special cases
if (MOZ_DOUBLE_IS_NaN(aValue)) { if (mozilla::IsNaN(aValue)) {
aDest.AppendLiteral("NaN"); aDest.AppendLiteral("NaN");
return; return;
} }
if (MOZ_DOUBLE_IS_INFINITE(aValue)) { if (mozilla::IsInfinite(aValue)) {
if (aValue < 0) if (aValue < 0)
aDest.Append(PRUnichar('-')); aDest.Append(PRUnichar('-'));
aDest.AppendLiteral("Infinity"); aDest.AppendLiteral("Infinity");

View File

@ -364,8 +364,8 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
// check for NaN or +/-Inf // check for NaN or +/-Inf
if (MOZ_DOUBLE_IS_NaN(start) || if (mozilla::IsNaN(start) ||
MOZ_DOUBLE_IS_INFINITE(start) || mozilla::IsInfinite(start) ||
start >= src.Length() + 0.5) { start >= src.Length() + 0.5) {
aContext->recycler()->getEmptyStringResult(aResult); aContext->recycler()->getEmptyStringResult(aResult);
@ -380,7 +380,7 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
end += start; end += start;
if (MOZ_DOUBLE_IS_NaN(end) || end < 0) { if (mozilla::IsNaN(end) || end < 0) {
aContext->recycler()->getEmptyStringResult(aResult); aContext->recycler()->getEmptyStringResult(aResult);
return NS_OK; return NS_OK;
@ -524,8 +524,8 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
rv = evaluateToNumber(mParams[0], aContext, &dbl); rv = evaluateToNumber(mParams[0], aContext, &dbl);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (!MOZ_DOUBLE_IS_NaN(dbl) && !MOZ_DOUBLE_IS_INFINITE(dbl)) { if (mozilla::IsFinite(dbl)) {
if (MOZ_DOUBLE_IS_NEGATIVE(dbl) && dbl >= -0.5) { if (mozilla::IsNegative(dbl) && dbl >= -0.5) {
dbl *= 0; dbl *= 0;
} }
else { else {
@ -541,11 +541,8 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
rv = evaluateToNumber(mParams[0], aContext, &dbl); rv = evaluateToNumber(mParams[0], aContext, &dbl);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (!MOZ_DOUBLE_IS_NaN(dbl) && if (mozilla::IsFinite(dbl) && !mozilla::IsNegativeZero(dbl))
!MOZ_DOUBLE_IS_INFINITE(dbl) &&
!(dbl == 0 && MOZ_DOUBLE_IS_NEGATIVE(dbl))) {
dbl = floor(dbl); dbl = floor(dbl);
}
return aContext->recycler()->getNumberResult(dbl, aResult); return aContext->recycler()->getNumberResult(dbl, aResult);
} }
@ -555,14 +552,12 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
rv = evaluateToNumber(mParams[0], aContext, &dbl); rv = evaluateToNumber(mParams[0], aContext, &dbl);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (!MOZ_DOUBLE_IS_NaN(dbl) && !MOZ_DOUBLE_IS_INFINITE(dbl)) { if (mozilla::IsFinite(dbl)) {
if (MOZ_DOUBLE_IS_NEGATIVE(dbl) && dbl > -1) { if (mozilla::IsNegative(dbl) && dbl > -1)
dbl *= 0; dbl *= 0;
} else
else {
dbl = ceil(dbl); dbl = ceil(dbl);
} }
}
return aContext->recycler()->getNumberResult(dbl, aResult); return aContext->recycler()->getNumberResult(dbl, aResult);
} }

View File

@ -39,16 +39,16 @@ txNumberExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
if (rightDbl == 0) { if (rightDbl == 0) {
#if defined(XP_WIN) #if defined(XP_WIN)
/* XXX MSVC miscompiles such that (NaN == 0) */ /* XXX MSVC miscompiles such that (NaN == 0) */
if (MOZ_DOUBLE_IS_NaN(rightDbl)) if (mozilla::IsNaN(rightDbl))
result = MOZ_DOUBLE_NaN(); result = mozilla::UnspecifiedNaN();
else else
#endif #endif
if (leftDbl == 0 || MOZ_DOUBLE_IS_NaN(leftDbl)) if (leftDbl == 0 || mozilla::IsNaN(leftDbl))
result = MOZ_DOUBLE_NaN(); result = mozilla::UnspecifiedNaN();
else if (MOZ_DOUBLE_IS_NEGATIVE(leftDbl) ^ MOZ_DOUBLE_IS_NEGATIVE(rightDbl)) else if (mozilla::IsNegative(leftDbl) != mozilla::IsNegative(rightDbl))
result = MOZ_DOUBLE_NEGATIVE_INFINITY(); result = mozilla::NegativeInfinity();
else else
result = MOZ_DOUBLE_POSITIVE_INFINITY(); result = mozilla::PositiveInfinity();
} }
else else
result = leftDbl / rightDbl; result = leftDbl / rightDbl;
@ -56,12 +56,12 @@ txNumberExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
case MODULUS: case MODULUS:
if (rightDbl == 0) { if (rightDbl == 0) {
result = MOZ_DOUBLE_NaN(); result = mozilla::UnspecifiedNaN();
} }
else { else {
#if defined(XP_WIN) #if defined(XP_WIN)
/* Workaround MS fmod bug where 42 % (1/0) => NaN, not 42. */ /* Workaround MS fmod bug where 42 % (1/0) => NaN, not 42. */
if (!MOZ_DOUBLE_IS_INFINITE(leftDbl) && MOZ_DOUBLE_IS_INFINITE(rightDbl)) if (!mozilla::IsInfinite(leftDbl) && mozilla::IsInfinite(rightDbl))
result = leftDbl; result = leftDbl;
else else
#endif #endif

View File

@ -49,7 +49,7 @@ bool NumberResult::booleanValue() {
// OG+ // OG+
// As per the XPath spec, the boolean value of a number is true if and only if // As per the XPath spec, the boolean value of a number is true if and only if
// it is neither positive 0 nor negative 0 nor NaN // it is neither positive 0 nor negative 0 nor NaN
return (bool)(value != 0.0 && !MOZ_DOUBLE_IS_NaN(value)); return (bool)(value != 0.0 && !mozilla::IsNaN(value));
// OG- // OG-
} //-- booleanValue } //-- booleanValue

View File

@ -28,7 +28,7 @@ double
txUnionNodeTest::getDefaultPriority() txUnionNodeTest::getDefaultPriority()
{ {
NS_ERROR("Don't call getDefaultPriority on txUnionPattern"); NS_ERROR("Don't call getDefaultPriority on txUnionPattern");
return MOZ_DOUBLE_NaN(); return mozilla::UnspecifiedNaN();
} }
bool bool

View File

@ -568,20 +568,20 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
if (nodes->isEmpty()) { if (nodes->isEmpty()) {
return aContext->recycler()-> return aContext->recycler()->
getNumberResult(MOZ_DOUBLE_NaN(), aResult); getNumberResult(UnspecifiedNaN(), aResult);
} }
bool findMax = mType == MAX; bool findMax = mType == MAX;
double res = findMax ? MOZ_DOUBLE_NEGATIVE_INFINITY() : double res = findMax ? mozilla::NegativeInfinity() :
MOZ_DOUBLE_POSITIVE_INFINITY(); mozilla::PositiveInfinity();
int32_t i, len = nodes->size(); int32_t i, len = nodes->size();
for (i = 0; i < len; ++i) { for (i = 0; i < len; ++i) {
nsAutoString str; nsAutoString str;
txXPathNodeUtils::appendNodeValue(nodes->get(i), str); txXPathNodeUtils::appendNodeValue(nodes->get(i), str);
double val = txDouble::toDouble(str); double val = txDouble::toDouble(str);
if (MOZ_DOUBLE_IS_NaN(val)) { if (mozilla::IsNaN(val)) {
res = MOZ_DOUBLE_NaN(); res = UnspecifiedNaN();
break; break;
} }
@ -611,15 +611,15 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
bool findMax = mType == HIGHEST; bool findMax = mType == HIGHEST;
double res = findMax ? MOZ_DOUBLE_NEGATIVE_INFINITY() : double res = findMax ? mozilla::NegativeInfinity() :
MOZ_DOUBLE_POSITIVE_INFINITY(); mozilla::PositiveInfinity();
int32_t i, len = nodes->size(); int32_t i, len = nodes->size();
for (i = 0; i < len; ++i) { for (i = 0; i < len; ++i) {
nsAutoString str; nsAutoString str;
const txXPathNode& node = nodes->get(i); const txXPathNode& node = nodes->get(i);
txXPathNodeUtils::appendNodeValue(node, str); txXPathNodeUtils::appendNodeValue(node, str);
double val = txDouble::toDouble(str); double val = txDouble::toDouble(str);
if (MOZ_DOUBLE_IS_NaN(val)) { if (mozilla::IsNaN(val)) {
resultSet->clear(); resultSet->clear();
break; break;
} }

View File

@ -81,16 +81,16 @@ txFormatNumberFunctionCall::evaluate(txIEvalContext* aContext,
} }
// Special cases // Special cases
if (MOZ_DOUBLE_IS_NaN(value)) { if (mozilla::IsNaN(value)) {
return aContext->recycler()->getStringResult(format->mNaN, aResult); return aContext->recycler()->getStringResult(format->mNaN, aResult);
} }
if (value == MOZ_DOUBLE_POSITIVE_INFINITY()) { if (value == mozilla::PositiveInfinity()) {
return aContext->recycler()->getStringResult(format->mInfinity, return aContext->recycler()->getStringResult(format->mInfinity,
aResult); aResult);
} }
if (value == MOZ_DOUBLE_NEGATIVE_INFINITY()) { if (value == mozilla::NegativeInfinity()) {
nsAutoString res; nsAutoString res;
res.Append(format->mMinusSign); res.Append(format->mMinusSign);
res.Append(format->mInfinity); res.Append(format->mInfinity);
@ -112,7 +112,7 @@ txFormatNumberFunctionCall::evaluate(txIEvalContext* aContext,
// Get right subexpression // Get right subexpression
inQuote = false; inQuote = false;
if (MOZ_DOUBLE_IS_NEGATIVE(value)) { if (mozilla::IsNegative(value)) {
while (pos < formatLen && while (pos < formatLen &&
(inQuote || (inQuote ||
formatStr.CharAt(pos) != format->mPatternSeparator)) { formatStr.CharAt(pos) != format->mPatternSeparator)) {

View File

@ -411,9 +411,9 @@ txStylesheet::addTemplate(txTemplateItem* aTemplate,
uint32_t unionPos = 1; // only used when unionPattern is set uint32_t unionPos = 1; // only used when unionPattern is set
while (simple) { while (simple) {
double priority = aTemplate->mPrio; double priority = aTemplate->mPrio;
if (MOZ_DOUBLE_IS_NaN(priority)) { if (mozilla::IsNaN(priority)) {
priority = simple->getDefaultPriority(); priority = simple->getDefaultPriority();
NS_ASSERTION(!MOZ_DOUBLE_IS_NaN(priority), NS_ASSERTION(!mozilla::IsNaN(priority),
"simple pattern without default priority"); "simple pattern without default priority");
} }

View File

@ -271,7 +271,7 @@ getNumberAttr(txStylesheetAttr* aAttributes,
txStylesheetCompilerState& aState, txStylesheetCompilerState& aState,
double& aNumber) double& aNumber)
{ {
aNumber = MOZ_DOUBLE_NaN(); aNumber = UnspecifiedNaN();
txStylesheetAttr* attr = nullptr; txStylesheetAttr* attr = nullptr;
nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None, nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
aName, aRequired, &attr); aName, aRequired, &attr);
@ -280,7 +280,7 @@ getNumberAttr(txStylesheetAttr* aAttributes,
} }
aNumber = txDouble::toDouble(attr->mValue); aNumber = txDouble::toDouble(attr->mValue);
if (MOZ_DOUBLE_IS_NaN(aNumber) && (aRequired || !aState.fcp())) { if (mozilla::IsNaN(aNumber) && (aRequired || !aState.fcp())) {
// XXX ErrorReport: number parse failure // XXX ErrorReport: number parse failure
return NS_ERROR_XSLT_PARSE_FAILURE; return NS_ERROR_XSLT_PARSE_FAILURE;
} }
@ -520,7 +520,7 @@ txFnStartLREStylesheet(int32_t aNamespaceID,
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
txExpandedName nullExpr; txExpandedName nullExpr;
double prio = MOZ_DOUBLE_NaN(); double prio = UnspecifiedNaN();
nsAutoPtr<txPattern> match(new txRootPattern()); nsAutoPtr<txPattern> match(new txRootPattern());
NS_ENSURE_TRUE(match, NS_ERROR_OUT_OF_MEMORY); NS_ENSURE_TRUE(match, NS_ERROR_OUT_OF_MEMORY);
@ -1113,7 +1113,7 @@ txFnStartTemplate(int32_t aNamespaceID,
aState, mode); aState, mode);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
double prio = MOZ_DOUBLE_NaN(); double prio = UnspecifiedNaN();
rv = getNumberAttr(aAttributes, aAttrCount, nsGkAtoms::priority, rv = getNumberAttr(aAttributes, aAttrCount, nsGkAtoms::priority,
false, aState, prio); false, aState, prio);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);

View File

@ -214,10 +214,10 @@ int txResultNumberComparator::compareValues(txObject* aVal1, txObject* aVal2)
double dval1 = ((NumberValue*)aVal1)->mVal; double dval1 = ((NumberValue*)aVal1)->mVal;
double dval2 = ((NumberValue*)aVal2)->mVal; double dval2 = ((NumberValue*)aVal2)->mVal;
if (MOZ_DOUBLE_IS_NaN(dval1)) if (mozilla::IsNaN(dval1))
return MOZ_DOUBLE_IS_NaN(dval2) ? 0 : -mAscending; return mozilla::IsNaN(dval2) ? 0 : -mAscending;
if (MOZ_DOUBLE_IS_NaN(dval2)) if (mozilla::IsNaN(dval2))
return mAscending; return mAscending;
if (dval1 == dval2) if (dval1 == dval2)

View File

@ -91,7 +91,7 @@ txXSLTNumber::getValueList(Expr* aValueExpr, txPattern* aCountPattern,
double value = result->numberValue(); double value = result->numberValue();
if (MOZ_DOUBLE_IS_INFINITE(value) || MOZ_DOUBLE_IS_NaN(value) || if (mozilla::IsInfinite(value) || mozilla::IsNaN(value) ||
value < 0.5) { value < 0.5) {
txDouble::toString(value, aValueString); txDouble::toString(value, aValueString);
return NS_OK; return NS_OK;

View File

@ -23,7 +23,7 @@
double txUnionPattern::getDefaultPriority() double txUnionPattern::getDefaultPriority()
{ {
NS_ERROR("Don't call getDefaultPriority on txUnionPattern"); NS_ERROR("Don't call getDefaultPriority on txUnionPattern");
return MOZ_DOUBLE_NaN(); return mozilla::UnspecifiedNaN();
} }
/* /*

View File

@ -1734,14 +1734,14 @@ ReportLenientThisUnwrappingFailure(JSContext* cx, JS::Handle<JSObject*> obj)
// Date implementation methods // Date implementation methods
Date::Date() : Date::Date() :
mMsecSinceEpoch(MOZ_DOUBLE_NaN()) mMsecSinceEpoch(UnspecifiedNaN())
{ {
} }
bool bool
Date::IsUndefined() const Date::IsUndefined() const
{ {
return MOZ_DOUBLE_IS_NaN(mMsecSinceEpoch); return IsNaN(mMsecSinceEpoch);
} }
bool bool

View File

@ -2256,11 +2256,11 @@ def numericValue(t, v):
if (t == IDLType.Tags.unrestricted_double or if (t == IDLType.Tags.unrestricted_double or
t == IDLType.Tags.unrestricted_float): t == IDLType.Tags.unrestricted_float):
if v == float("inf"): if v == float("inf"):
return "MOZ_DOUBLE_POSITIVE_INFINITY()" return "mozilla::PositiveInfinity()"
if v == float("-inf"): if v == float("-inf"):
return "MOZ_DOUBLE_NEGATIVE_INFINITY()" return "mozilla::NegativeInfinity()"
if math.isnan(v): if math.isnan(v):
return "MOZ_DOUBLE_NaN()" return "mozilla::UnspecifiedNaN()"
return "%s%s" % (v, numericSuffixes[t]) return "%s%s" % (v, numericSuffixes[t])
class CastableObjectUnwrapper(): class CastableObjectUnwrapper():
@ -3393,8 +3393,8 @@ for (uint32_t i = 0; i < length; ++i) {
else: else:
nonFiniteCode = (" ThrowErrorMessage(cx, MSG_NOT_FINITE);\n" nonFiniteCode = (" ThrowErrorMessage(cx, MSG_NOT_FINITE);\n"
"%s" % exceptionCodeIndented.define()) "%s" % exceptionCodeIndented.define())
template += (" else if (!MOZ_DOUBLE_IS_FINITE(%s)) {\n" template += (" else if (!mozilla::IsFinite(%s)) {\n"
" // Note: MOZ_DOUBLE_IS_FINITE will do the right thing\n" " // Note: mozilla::IsFinite will do the right thing\n"
" // when passed a non-finite float too.\n" " // when passed a non-finite float too.\n"
"%s\n" "%s\n"
"}" % (readLoc, nonFiniteCode)) "}" % (readLoc, nonFiniteCode))

View File

@ -223,7 +223,7 @@ PrimitiveConversionTraits_EnforceRange(JSContext* cx, const double& d, T* retval
MOZ_STATIC_ASSERT(std::numeric_limits<T>::is_integer, MOZ_STATIC_ASSERT(std::numeric_limits<T>::is_integer,
"This can only be applied to integers!"); "This can only be applied to integers!");
if (!MOZ_DOUBLE_IS_FINITE(d)) { if (!mozilla::IsFinite(d)) {
return ThrowErrorMessage(cx, MSG_ENFORCE_RANGE_NON_FINITE, TypeName<T>::value()); return ThrowErrorMessage(cx, MSG_ENFORCE_RANGE_NON_FINITE, TypeName<T>::value());
} }
@ -251,7 +251,7 @@ PrimitiveConversionTraits_Clamp(JSContext* cx, const double& d, T* retval)
MOZ_STATIC_ASSERT(std::numeric_limits<T>::is_integer, MOZ_STATIC_ASSERT(std::numeric_limits<T>::is_integer,
"This can only be applied to integers!"); "This can only be applied to integers!");
if (MOZ_DOUBLE_IS_NaN(d)) { if (mozilla::IsNaN(d)) {
*retval = 0; *retval = 0;
return true; return true;
} }
@ -264,7 +264,7 @@ PrimitiveConversionTraits_Clamp(JSContext* cx, const double& d, T* retval)
return true; return true;
} }
MOZ_ASSERT(MOZ_DOUBLE_IS_FINITE(d)); MOZ_ASSERT(mozilla::IsFinite(d));
// Banker's rounding (round ties towards even). // Banker's rounding (round ties towards even).
// We move away from 0 by 0.5f and then truncate. That gets us the right // We move away from 0 by 0.5f and then truncate. That gets us the right

View File

@ -125,7 +125,7 @@ Key::EncodeJSValInternal(JSContext* aCx, const jsval aVal,
if (JSVAL_IS_DOUBLE(aVal)) { if (JSVAL_IS_DOUBLE(aVal)) {
double d = JSVAL_TO_DOUBLE(aVal); double d = JSVAL_TO_DOUBLE(aVal);
if (MOZ_DOUBLE_IS_NaN(d)) { if (mozilla::IsNaN(d)) {
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR; return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
} }
EncodeNumber(d, eFloat + aTypeOffset); EncodeNumber(d, eFloat + aTypeOffset);

View File

@ -4772,8 +4772,8 @@ gfxFontStyle::gfxFontStyle(uint8_t aStyle, uint16_t aWeight, int16_t aStretch,
systemFont(aSystemFont), printerFont(aPrinterFont), systemFont(aSystemFont), printerFont(aPrinterFont),
style(aStyle) style(aStyle)
{ {
MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(size)); MOZ_ASSERT(!mozilla::IsNaN(size));
MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(sizeAdjust)); MOZ_ASSERT(!mozilla::IsNaN(sizeAdjust));
if (weight > 900) if (weight > 900)
weight = 900; weight = 900;

View File

@ -924,14 +924,14 @@ class Value
bool setNumber(double d) { bool setNumber(double d) {
int32_t i; int32_t i;
if (MOZ_DOUBLE_IS_INT32(d, &i)) { if (mozilla::DoubleIsInt32(d, &i)) {
setInt32(i); setInt32(i);
return true; return true;
} else { }
setDouble(d); setDouble(d);
return false; return false;
} }
}
void setObjectOrNull(JSObject *arg) { void setObjectOrNull(JSObject *arg) {
if (arg) if (arg)

View File

@ -40,6 +40,9 @@
using namespace js; using namespace js;
using mozilla::IsFinite;
using mozilla::IsNegativeZero;
#if ENABLE_INTL_API #if ENABLE_INTL_API
using icu::Locale; using icu::Locale;
using icu::NumberingSystem; using icu::NumberingSystem;
@ -1429,7 +1432,7 @@ static bool
intl_FormatNumber(JSContext *cx, UNumberFormat *nf, double x, MutableHandleValue result) intl_FormatNumber(JSContext *cx, UNumberFormat *nf, double x, MutableHandleValue result)
{ {
// FormatNumber doesn't consider -0.0 to be negative. // FormatNumber doesn't consider -0.0 to be negative.
if (MOZ_DOUBLE_IS_NEGATIVE_ZERO(x)) if (IsNegativeZero(x))
x = 0.0; x = 0.0;
StringBuffer chars(cx); StringBuffer chars(cx);
@ -1908,7 +1911,7 @@ NewUDateFormat(JSContext *cx, HandleObject dateTimeFormat)
static bool static bool
intl_FormatDateTime(JSContext *cx, UDateFormat *df, double x, MutableHandleValue result) intl_FormatDateTime(JSContext *cx, UDateFormat *df, double x, MutableHandleValue result)
{ {
if (!MOZ_DOUBLE_IS_FINITE(x)) { if (!IsFinite(x)) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_DATE_NOT_FINITE); JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_DATE_NOT_FINITE);
return false; return false;
} }

View File

@ -19,6 +19,9 @@
using namespace js; using namespace js;
using mozilla::DoubleIsInt32;
using mozilla::IsNaN;
/*** OrderedHashTable ****************************************************************************/ /*** OrderedHashTable ****************************************************************************/
@ -790,10 +793,10 @@ HashableValue::setValue(JSContext *cx, const Value &v)
} else if (v.isDouble()) { } else if (v.isDouble()) {
double d = v.toDouble(); double d = v.toDouble();
int32_t i; int32_t i;
if (MOZ_DOUBLE_IS_INT32(d, &i)) { if (DoubleIsInt32(d, &i)) {
// Normalize int32_t-valued doubles to int32_t for faster hashing and testing. // Normalize int32_t-valued doubles to int32_t for faster hashing and testing.
value = Int32Value(i); value = Int32Value(i);
} else if (MOZ_DOUBLE_IS_NaN(d)) { } else if (IsNaN(d)) {
// NaNs with different bits must hash and test identically. // NaNs with different bits must hash and test identically.
value = DoubleValue(js_NaN); value = DoubleValue(js_NaN);
} else { } else {

View File

@ -1904,7 +1904,7 @@ jsvalToIntegerExplicit(jsval val, IntegerType* result)
if (JSVAL_IS_DOUBLE(val)) { if (JSVAL_IS_DOUBLE(val)) {
// Convert -Inf, Inf, and NaN to 0; otherwise, convert by C-style cast. // Convert -Inf, Inf, and NaN to 0; otherwise, convert by C-style cast.
double d = JSVAL_TO_DOUBLE(val); double d = JSVAL_TO_DOUBLE(val);
*result = MOZ_DOUBLE_IS_FINITE(d) ? IntegerType(d) : 0; *result = mozilla::IsFinite(d) ? IntegerType(d) : 0;
return true; return true;
} }
if (!JSVAL_IS_PRIMITIVE(val)) { if (!JSVAL_IS_PRIMITIVE(val)) {

View File

@ -52,6 +52,7 @@ using namespace js::gc;
using namespace js::frontend; using namespace js::frontend;
using mozilla::DebugOnly; using mozilla::DebugOnly;
using mozilla::DoubleIsInt32;
using mozilla::PodCopy; using mozilla::PodCopy;
static bool static bool
@ -2115,7 +2116,7 @@ EmitNumberOp(JSContext *cx, double dval, BytecodeEmitter *bce)
ptrdiff_t off; ptrdiff_t off;
jsbytecode *pc; jsbytecode *pc;
if (MOZ_DOUBLE_IS_INT32(dval, &ival)) { if (DoubleIsInt32(dval, &ival)) {
if (ival == 0) if (ival == 0)
return Emit1(cx, bce, JSOP_ZERO) >= 0; return Emit1(cx, bce, JSOP_ZERO) >= 0;
if (ival == 1) if (ival == 1)
@ -2272,7 +2273,7 @@ EmitSwitch(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
} }
int32_t i; int32_t i;
if (!MOZ_DOUBLE_IS_INT32(pn4->pn_dval, &i)) { if (!DoubleIsInt32(pn4->pn_dval, &i)) {
switchOp = JSOP_CONDSWITCH; switchOp = JSOP_CONDSWITCH;
continue; continue;
} }

View File

@ -21,6 +21,9 @@
using namespace js; using namespace js;
using namespace js::frontend; using namespace js::frontend;
using mozilla::IsNaN;
using mozilla::IsNegative;
static ParseNode * static ParseNode *
ContainsVarOrConst(ParseNode *pn) ContainsVarOrConst(ParseNode *pn)
{ {
@ -147,13 +150,13 @@ FoldBinaryNumeric(JSContext *cx, JSOp op, ParseNode *pn1, ParseNode *pn2,
if (d2 == 0) { if (d2 == 0) {
#if defined(XP_WIN) #if defined(XP_WIN)
/* XXX MSVC miscompiles such that (NaN == 0) */ /* XXX MSVC miscompiles such that (NaN == 0) */
if (MOZ_DOUBLE_IS_NaN(d2)) if (IsNaN(d2))
d = js_NaN; d = js_NaN;
else else
#endif #endif
if (d == 0 || MOZ_DOUBLE_IS_NaN(d)) if (d == 0 || IsNaN(d))
d = js_NaN; d = js_NaN;
else if (MOZ_DOUBLE_IS_NEGATIVE(d) != MOZ_DOUBLE_IS_NEGATIVE(d2)) else if (IsNegative(d) != IsNegative(d2))
d = js_NegativeInfinity; d = js_NegativeInfinity;
else else
d = js_PositiveInfinity; d = js_PositiveInfinity;
@ -202,7 +205,7 @@ Boolish(ParseNode *pn)
{ {
switch (pn->getOp()) { switch (pn->getOp()) {
case JSOP_DOUBLE: case JSOP_DOUBLE:
return (pn->pn_dval != 0 && !MOZ_DOUBLE_IS_NaN(pn->pn_dval)) ? Truthy : Falsy; return (pn->pn_dval != 0 && !IsNaN(pn->pn_dval)) ? Truthy : Falsy;
case JSOP_STRING: case JSOP_STRING:
return (pn->pn_atom->length() > 0) ? Truthy : Falsy; return (pn->pn_atom->length() > 0) ? Truthy : Falsy;
@ -396,7 +399,7 @@ FoldConstants<FullParseHandler>(JSContext *cx, ParseNode **pnp,
/* Reduce 'if (C) T; else E' into T for true C, E for false. */ /* Reduce 'if (C) T; else E' into T for true C, E for false. */
switch (pn1->getKind()) { switch (pn1->getKind()) {
case PNK_NUMBER: case PNK_NUMBER:
if (pn1->pn_dval == 0 || MOZ_DOUBLE_IS_NaN(pn1->pn_dval)) if (pn1->pn_dval == 0 || IsNaN(pn1->pn_dval))
pn2 = pn3; pn2 = pn3;
break; break;
case PNK_STRING: case PNK_STRING:
@ -678,7 +681,7 @@ FoldConstants<FullParseHandler>(JSContext *cx, ParseNode **pnp,
break; break;
case JSOP_NOT: case JSOP_NOT:
if (d == 0 || MOZ_DOUBLE_IS_NaN(d)) { if (d == 0 || IsNaN(d)) {
pn->setKind(PNK_TRUE); pn->setKind(PNK_TRUE);
pn->setOp(JSOP_TRUE); pn->setOp(JSOP_TRUE);
} else { } else {

View File

@ -17,6 +17,8 @@
using namespace js; using namespace js;
using namespace js::frontend; using namespace js::frontend;
using mozilla::IsFinite;
/* /*
* Asserts to verify assumptions behind pn_ macros. * Asserts to verify assumptions behind pn_ macros.
*/ */
@ -635,7 +637,7 @@ NullaryNode::dump()
case PNK_NUMBER: { case PNK_NUMBER: {
ToCStringBuf cbuf; ToCStringBuf cbuf;
const char *cstr = NumberToCString(NULL, &cbuf, pn_dval); const char *cstr = NumberToCString(NULL, &cbuf, pn_dval);
if (!MOZ_DOUBLE_IS_FINITE(pn_dval)) if (!IsFinite(pn_dval))
fputc('#', stderr); fputc('#', stderr);
if (cstr) if (cstr)
fprintf(stderr, "%s", cstr); fprintf(stderr, "%s", cstr);

View File

@ -151,8 +151,8 @@ ValidateGlobalConstant(JSContext *cx, AsmJSModule::Global &global, HandleValue g
return LinkFail(cx, "global constant value needs to be a number"); return LinkFail(cx, "global constant value needs to be a number");
// NaN != NaN // NaN != NaN
if (MOZ_DOUBLE_IS_NaN(global.constantValue())) { if (IsNaN(global.constantValue())) {
if (!MOZ_DOUBLE_IS_NaN(v.toNumber())) if (!IsNaN(v.toNumber()))
return LinkFail(cx, "global constant value needs to be NaN"); return LinkFail(cx, "global constant value needs to be NaN");
} else { } else {
if (v.toNumber() != global.constantValue()) if (v.toNumber() != global.constantValue())

View File

@ -22,6 +22,10 @@ using namespace js;
using namespace js::ion; using namespace js::ion;
using mozilla::Abs; using mozilla::Abs;
using mozilla::ExponentComponent;
using mozilla::IsInfinite;
using mozilla::IsNaN;
using mozilla::IsNegative;
// This algorithm is based on the paper "Eliminating Range Checks Using // This algorithm is based on the paper "Eliminating Range Checks Using
// Static Single Assignment Form" by Gough and Klaren. // Static Single Assignment Form" by Gough and Klaren.
@ -579,14 +583,14 @@ MConstant::computeRange()
int exp = Range::MaxDoubleExponent; int exp = Range::MaxDoubleExponent;
// NaN is estimated as a Double which covers everything. // NaN is estimated as a Double which covers everything.
if (MOZ_DOUBLE_IS_NaN(d)) { if (IsNaN(d)) {
setRange(new Range(RANGE_INF_MIN, RANGE_INF_MAX, true, exp)); setRange(new Range(RANGE_INF_MIN, RANGE_INF_MAX, true, exp));
return; return;
} }
// Infinity is used to set both lower and upper to the range boundaries. // Infinity is used to set both lower and upper to the range boundaries.
if (MOZ_DOUBLE_IS_INFINITE(d)) { if (IsInfinite(d)) {
if (MOZ_DOUBLE_IS_NEGATIVE(d)) if (IsNegative(d))
setRange(new Range(RANGE_INF_MIN, RANGE_INF_MIN, false, exp)); setRange(new Range(RANGE_INF_MIN, RANGE_INF_MIN, false, exp));
else else
setRange(new Range(RANGE_INF_MAX, RANGE_INF_MAX, false, exp)); setRange(new Range(RANGE_INF_MAX, RANGE_INF_MAX, false, exp));
@ -594,10 +598,10 @@ MConstant::computeRange()
} }
// Extract the exponent, to approximate it with the range analysis. // Extract the exponent, to approximate it with the range analysis.
exp = MOZ_DOUBLE_EXPONENT(d); exp = ExponentComponent(d);
if (exp < 0) { if (exp < 0) {
// This double only has a decimal part. // This double only has a decimal part.
if (MOZ_DOUBLE_IS_NEGATIVE(d)) if (IsNegative(d))
setRange(new Range(-1, 0, true, 0)); setRange(new Range(-1, 0, true, 0));
else else
setRange(new Range(0, 1, true, 0)); setRange(new Range(0, 1, true, 0));
@ -614,7 +618,7 @@ MConstant::computeRange()
} else { } else {
// This double has a precision loss. This also mean that it cannot // This double has a precision loss. This also mean that it cannot
// encode any decimals. // encode any decimals.
if (MOZ_DOUBLE_IS_NEGATIVE(d)) if (IsNegative(d))
setRange(new Range(RANGE_INF_MIN, RANGE_INF_MIN, false, exp)); setRange(new Range(RANGE_INF_MIN, RANGE_INF_MIN, false, exp));
else else
setRange(new Range(RANGE_INF_MAX, RANGE_INF_MAX, false, exp)); setRange(new Range(RANGE_INF_MAX, RANGE_INF_MAX, false, exp));

View File

@ -102,10 +102,10 @@ class Range : public TempObject {
// Maximal exponenent under which we have no precission loss on double // Maximal exponenent under which we have no precission loss on double
// operations. Double has 52 bits of mantissa, so 2^52+1 cannot be // operations. Double has 52 bits of mantissa, so 2^52+1 cannot be
// represented without loss. // represented without loss.
static const uint16_t MaxTruncatableExponent = MOZ_DOUBLE_EXPONENT_SHIFT; static const uint16_t MaxTruncatableExponent = mozilla::DoubleExponentShift;
// 11 bits of signed exponent, so the max is encoded on 10 bits. // 11 bits of signed exponent, so the max is encoded on 10 bits.
static const uint16_t MaxDoubleExponent = MOZ_DOUBLE_EXPONENT_BIAS; static const uint16_t MaxDoubleExponent = mozilla::DoubleExponentBias;
private: private:
// Absolute ranges. // Absolute ranges.

View File

@ -21,6 +21,8 @@ using namespace js;
using namespace js::ion; using namespace js::ion;
using mozilla::DebugOnly; using mozilla::DebugOnly;
using mozilla::DoubleExponentBias;
using mozilla::DoubleExponentShift;
CodeGeneratorX86::CodeGeneratorX86(MIRGenerator *gen, LIRGraph *graph, MacroAssembler *masm) CodeGeneratorX86::CodeGeneratorX86(MIRGenerator *gen, LIRGraph *graph, MacroAssembler *masm)
: CodeGeneratorX86Shared(gen, graph, masm) : CodeGeneratorX86Shared(gen, graph, masm)
@ -715,8 +717,8 @@ CodeGeneratorX86::visitOutOfLineTruncate(OutOfLineTruncate *ool)
masm.movsd(input, Operand(esp, 0)); masm.movsd(input, Operand(esp, 0));
static const uint32_t EXPONENT_MASK = 0x7ff00000; static const uint32_t EXPONENT_MASK = 0x7ff00000;
static const uint32_t EXPONENT_SHIFT = MOZ_DOUBLE_EXPONENT_SHIFT - 32; static const uint32_t EXPONENT_SHIFT = DoubleExponentShift - 32;
static const uint32_t TOO_BIG_EXPONENT = (MOZ_DOUBLE_EXPONENT_BIAS + 63) << EXPONENT_SHIFT; static const uint32_t TOO_BIG_EXPONENT = (DoubleExponentBias + 63) << EXPONENT_SHIFT;
// Check exponent to avoid fp exceptions. // Check exponent to avoid fp exceptions.
Label failPopDouble; Label failPopDouble;

View File

@ -502,7 +502,7 @@ JS_ValueToNumber(JSContext *cx, jsval valueArg, double *dp)
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_DoubleIsInt32(double d, int32_t *ip) JS_DoubleIsInt32(double d, int32_t *ip)
{ {
return MOZ_DOUBLE_IS_INT32(d, ip); return mozilla::DoubleIsInt32(d, ip);
} }
JS_PUBLIC_API(int32_t) JS_PUBLIC_API(int32_t)
@ -566,7 +566,7 @@ JS_ValueToInt32(JSContext *cx, jsval vArg, int32_t *ip)
return false; return false;
} }
if (MOZ_DOUBLE_IS_NaN(d) || d <= -2147483649.0 || 2147483648.0 <= d) { if (mozilla::IsNaN(d) || d <= -2147483649.0 || 2147483648.0 <= d) {
js_ReportValueError(cx, JSMSG_CANT_CONVERT, js_ReportValueError(cx, JSMSG_CANT_CONVERT,
JSDVG_SEARCH_STACK, v, NullPtr()); JSDVG_SEARCH_STACK, v, NullPtr());
return false; return false;

View File

@ -1164,7 +1164,7 @@ JS_NumberValue(double d)
{ {
int32_t i; int32_t i;
d = JS_CANONICALIZE_NAN(d); d = JS_CANONICALIZE_NAN(d);
if (MOZ_DOUBLE_IS_INT32(d, &i)) if (mozilla::DoubleIsInt32(d, &i))
return INT_TO_JSVAL(i); return INT_TO_JSVAL(i);
return DOUBLE_TO_JSVAL(d); return DOUBLE_TO_JSVAL(d);
} }
@ -1543,7 +1543,7 @@ ToBoolean(const Value &v)
return false; return false;
if (v.isDouble()) { if (v.isDouble()) {
double d = v.toDouble(); double d = v.toDouble();
return !MOZ_DOUBLE_IS_NaN(d) && d != 0; return !mozilla::IsNaN(d) && d != 0;
} }
/* The slow path handles strings and objects. */ /* The slow path handles strings and objects. */

View File

@ -47,6 +47,7 @@ using namespace js::types;
using mozilla::ArrayLength; using mozilla::ArrayLength;
using mozilla::DebugOnly; using mozilla::DebugOnly;
using mozilla::IsNaN;
using mozilla::PointerRangeSize; using mozilla::PointerRangeSize;
JSBool JSBool
@ -1471,7 +1472,7 @@ SortComparatorFunction::operator()(const Value &a, const Value &b, bool *lessOrE
* 'consistent compare functions' that don't return NaN, but is silent * 'consistent compare functions' that don't return NaN, but is silent
* about what the result should be. So we currently ignore it. * about what the result should be. So we currently ignore it.
*/ */
*lessOrEqualp = (MOZ_DOUBLE_IS_NaN(cmp) || cmp <= 0); *lessOrEqualp = (IsNaN(cmp) || cmp <= 0);
return true; return true;
} }

View File

@ -41,6 +41,8 @@
#include "vm/RegExpObject-inl.h" #include "vm/RegExpObject-inl.h"
using namespace js; using namespace js;
using mozilla::IsNaN;
using mozilla::LittleEndian; using mozilla::LittleEndian;
using mozilla::NativeEndian; using mozilla::NativeEndian;
@ -1058,7 +1060,7 @@ JSStructuredCloneReader::startRead(Value *vp)
double d; double d;
if (!in.readDouble(&d) || !checkDouble(d)) if (!in.readDouble(&d) || !checkDouble(d))
return false; return false;
if (!MOZ_DOUBLE_IS_NaN(d) && d != TimeClip(d)) { if (!IsNaN(d) && d != TimeClip(d)) {
JS_ReportErrorNumber(context(), js_GetErrorMessage, NULL, JSMSG_SC_BAD_SERIALIZED_DATA, JS_ReportErrorNumber(context(), js_GetErrorMessage, NULL, JSMSG_SC_BAD_SERIALIZED_DATA,
"date"); "date");
return false; return false;

View File

@ -53,6 +53,8 @@ using namespace js;
using namespace js::types; using namespace js::types;
using mozilla::ArrayLength; using mozilla::ArrayLength;
using mozilla::IsFinite;
using mozilla::IsNaN;
/* /*
* The JS 'Date' object is patterned after the Java 'Date' object. * The JS 'Date' object is patterned after the Java 'Date' object.
@ -128,7 +130,7 @@ IsLeapYear(double year)
inline double inline double
DaysInYear(double year) DaysInYear(double year)
{ {
if (!MOZ_DOUBLE_IS_FINITE(year)) if (!IsFinite(year))
return js_NaN; return js_NaN;
return IsLeapYear(year) ? 366 : 365; return IsLeapYear(year) ? 366 : 365;
} }
@ -151,7 +153,7 @@ TimeFromYear(double y)
static double static double
YearFromTime(double t) YearFromTime(double t)
{ {
if (!MOZ_DOUBLE_IS_FINITE(t)) if (!IsFinite(t))
return js_NaN; return js_NaN;
JS_ASSERT(ToInteger(t) == t); JS_ASSERT(ToInteger(t) == t);
@ -183,14 +185,14 @@ DaysInFebruary(double year)
inline double inline double
DayWithinYear(double t, double year) DayWithinYear(double t, double year)
{ {
JS_ASSERT_IF(MOZ_DOUBLE_IS_FINITE(t), YearFromTime(t) == year); JS_ASSERT_IF(IsFinite(t), YearFromTime(t) == year);
return Day(t) - DayFromYear(year); return Day(t) - DayFromYear(year);
} }
static double static double
MonthFromTime(double t) MonthFromTime(double t)
{ {
if (!MOZ_DOUBLE_IS_FINITE(t)) if (!IsFinite(t))
return js_NaN; return js_NaN;
double year = YearFromTime(t); double year = YearFromTime(t);
@ -226,7 +228,7 @@ MonthFromTime(double t)
static double static double
DateFromTime(double t) DateFromTime(double t)
{ {
if (!MOZ_DOUBLE_IS_FINITE(t)) if (!IsFinite(t))
return js_NaN; return js_NaN;
double year = YearFromTime(t); double year = YearFromTime(t);
@ -309,7 +311,7 @@ static double
MakeDay(double year, double month, double date) MakeDay(double year, double month, double date)
{ {
/* Step 1. */ /* Step 1. */
if (!MOZ_DOUBLE_IS_FINITE(year) || !MOZ_DOUBLE_IS_FINITE(month) || !MOZ_DOUBLE_IS_FINITE(date)) if (!IsFinite(year) || !IsFinite(month) || !IsFinite(date))
return js_NaN; return js_NaN;
/* Steps 2-4. */ /* Steps 2-4. */
@ -339,7 +341,7 @@ inline double
MakeDate(double day, double time) MakeDate(double day, double time)
{ {
/* Step 1. */ /* Step 1. */
if (!MOZ_DOUBLE_IS_FINITE(day) || !MOZ_DOUBLE_IS_FINITE(time)) if (!IsFinite(day) || !IsFinite(time))
return js_NaN; return js_NaN;
/* Step 2. */ /* Step 2. */
@ -405,7 +407,7 @@ EquivalentYearForDST(int year)
static double static double
DaylightSavingTA(double t, DateTimeInfo *dtInfo) DaylightSavingTA(double t, DateTimeInfo *dtInfo)
{ {
if (!MOZ_DOUBLE_IS_FINITE(t)) if (!IsFinite(t))
return js_NaN; return js_NaN;
/* /*
@ -486,10 +488,10 @@ static double
MakeTime(double hour, double min, double sec, double ms) MakeTime(double hour, double min, double sec, double ms)
{ {
/* Step 1. */ /* Step 1. */
if (!MOZ_DOUBLE_IS_FINITE(hour) || if (!IsFinite(hour) ||
!MOZ_DOUBLE_IS_FINITE(min) || !IsFinite(min) ||
!MOZ_DOUBLE_IS_FINITE(sec) || !IsFinite(sec) ||
!MOZ_DOUBLE_IS_FINITE(ms)) !IsFinite(ms))
{ {
return js_NaN; return js_NaN;
} }
@ -619,7 +621,7 @@ date_msecFromArgs(JSContext *cx, CallArgs args, double *rval)
if (!ToNumber(cx, args[loop], &d)) if (!ToNumber(cx, args[loop], &d))
return JS_FALSE; return JS_FALSE;
/* return NaN if any arg is not finite */ /* return NaN if any arg is not finite */
if (!MOZ_DOUBLE_IS_FINITE(d)) { if (!IsFinite(d)) {
*rval = js_NaN; *rval = js_NaN;
return JS_TRUE; return JS_TRUE;
} }
@ -1281,7 +1283,7 @@ FillLocalTimeSlots(DateTimeInfo *dtInfo, JSObject *obj)
double utcTime = obj->getDateUTCTime().toNumber(); double utcTime = obj->getDateUTCTime().toNumber();
if (!MOZ_DOUBLE_IS_FINITE(utcTime)) { if (!IsFinite(utcTime)) {
for (size_t ind = JSObject::JSSLOT_DATE_COMPONENTS_START; for (size_t ind = JSObject::JSSLOT_DATE_COMPONENTS_START;
ind < JSObject::DATE_CLASS_RESERVED_SLOTS; ind < JSObject::DATE_CLASS_RESERVED_SLOTS;
ind++) { ind++) {
@ -1483,7 +1485,7 @@ date_getUTCFullYear_impl(JSContext *cx, CallArgs args)
JS_ASSERT(IsDate(args.thisv())); JS_ASSERT(IsDate(args.thisv()));
double result = args.thisv().toObject().getDateUTCTime().toNumber(); double result = args.thisv().toObject().getDateUTCTime().toNumber();
if (MOZ_DOUBLE_IS_FINITE(result)) if (IsFinite(result))
result = YearFromTime(result); result = YearFromTime(result);
args.rval().setNumber(result); args.rval().setNumber(result);
@ -1558,7 +1560,7 @@ date_getUTCDate_impl(JSContext *cx, CallArgs args)
JS_ASSERT(IsDate(args.thisv())); JS_ASSERT(IsDate(args.thisv()));
double result = args.thisv().toObject().getDateUTCTime().toNumber(); double result = args.thisv().toObject().getDateUTCTime().toNumber();
if (MOZ_DOUBLE_IS_FINITE(result)) if (IsFinite(result))
result = DateFromTime(result); result = DateFromTime(result);
args.rval().setNumber(result); args.rval().setNumber(result);
@ -1597,7 +1599,7 @@ date_getUTCDay_impl(JSContext *cx, CallArgs args)
JS_ASSERT(IsDate(args.thisv())); JS_ASSERT(IsDate(args.thisv()));
double result = args.thisv().toObject().getDateUTCTime().toNumber(); double result = args.thisv().toObject().getDateUTCTime().toNumber();
if (MOZ_DOUBLE_IS_FINITE(result)) if (IsFinite(result))
result = WeekDay(result); result = WeekDay(result);
args.rval().setNumber(result); args.rval().setNumber(result);
@ -1636,7 +1638,7 @@ date_getUTCHours_impl(JSContext *cx, CallArgs args)
JS_ASSERT(IsDate(args.thisv())); JS_ASSERT(IsDate(args.thisv()));
double result = args.thisv().toObject().getDateUTCTime().toNumber(); double result = args.thisv().toObject().getDateUTCTime().toNumber();
if (MOZ_DOUBLE_IS_FINITE(result)) if (IsFinite(result))
result = HourFromTime(result); result = HourFromTime(result);
args.rval().setNumber(result); args.rval().setNumber(result);
@ -1675,7 +1677,7 @@ date_getUTCMinutes_impl(JSContext *cx, CallArgs args)
JS_ASSERT(IsDate(args.thisv())); JS_ASSERT(IsDate(args.thisv()));
double result = args.thisv().toObject().getDateUTCTime().toNumber(); double result = args.thisv().toObject().getDateUTCTime().toNumber();
if (MOZ_DOUBLE_IS_FINITE(result)) if (IsFinite(result))
result = MinFromTime(result); result = MinFromTime(result);
args.rval().setNumber(result); args.rval().setNumber(result);
@ -1718,7 +1720,7 @@ date_getUTCMilliseconds_impl(JSContext *cx, CallArgs args)
JS_ASSERT(IsDate(args.thisv())); JS_ASSERT(IsDate(args.thisv()));
double result = args.thisv().toObject().getDateUTCTime().toNumber(); double result = args.thisv().toObject().getDateUTCTime().toNumber();
if (MOZ_DOUBLE_IS_FINITE(result)) if (IsFinite(result))
result = msFromTime(result); result = msFromTime(result);
args.rval().setNumber(result); args.rval().setNumber(result);
@ -2312,7 +2314,7 @@ static double
ThisLocalTimeOrZero(HandleObject date, DateTimeInfo *dtInfo) ThisLocalTimeOrZero(HandleObject date, DateTimeInfo *dtInfo)
{ {
double t = date->getDateUTCTime().toNumber(); double t = date->getDateUTCTime().toNumber();
if (MOZ_DOUBLE_IS_NaN(t)) if (IsNaN(t))
return +0; return +0;
return LocalTime(t, dtInfo); return LocalTime(t, dtInfo);
} }
@ -2321,7 +2323,7 @@ static double
ThisUTCTimeOrZero(HandleObject date) ThisUTCTimeOrZero(HandleObject date)
{ {
double t = date->getDateUTCTime().toNumber(); double t = date->getDateUTCTime().toNumber();
return MOZ_DOUBLE_IS_NaN(t) ? +0 : t; return IsNaN(t) ? +0 : t;
} }
/* ES5 15.9.5.40. */ /* ES5 15.9.5.40. */
@ -2429,7 +2431,7 @@ date_setYear_impl(JSContext *cx, CallArgs args)
return false; return false;
/* Step 3. */ /* Step 3. */
if (MOZ_DOUBLE_IS_NaN(y)) { if (IsNaN(y)) {
SetUTCTime(thisObj, js_NaN, args.rval().address()); SetUTCTime(thisObj, js_NaN, args.rval().address());
return true; return true;
} }
@ -2508,7 +2510,7 @@ date_toGMTString_impl(JSContext *cx, CallArgs args)
double utctime = args.thisv().toObject().getDateUTCTime().toNumber(); double utctime = args.thisv().toObject().getDateUTCTime().toNumber();
char buf[100]; char buf[100];
if (!MOZ_DOUBLE_IS_FINITE(utctime)) if (!IsFinite(utctime))
JS_snprintf(buf, sizeof buf, js_NaN_date_str); JS_snprintf(buf, sizeof buf, js_NaN_date_str);
else else
print_gmt_string(buf, sizeof buf, utctime); print_gmt_string(buf, sizeof buf, utctime);
@ -2534,7 +2536,7 @@ date_toISOString_impl(JSContext *cx, CallArgs args)
JS_ASSERT(IsDate(args.thisv())); JS_ASSERT(IsDate(args.thisv()));
double utctime = args.thisv().toObject().getDateUTCTime().toNumber(); double utctime = args.thisv().toObject().getDateUTCTime().toNumber();
if (!MOZ_DOUBLE_IS_FINITE(utctime)) { if (!IsFinite(utctime)) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INVALID_DATE); JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INVALID_DATE);
return false; return false;
} }
@ -2574,7 +2576,7 @@ date_toJSON(JSContext *cx, unsigned argc, Value *vp)
return false; return false;
/* Step 3. */ /* Step 3. */
if (tv.isDouble() && !MOZ_DOUBLE_IS_FINITE(tv.toDouble())) { if (tv.isDouble() && !IsFinite(tv.toDouble())) {
args.rval().setNull(); args.rval().setNull();
return true; return true;
} }
@ -2641,7 +2643,7 @@ date_format(JSContext *cx, double date, formatspec format, MutableHandleValue rv
size_t i, tzlen; size_t i, tzlen;
PRMJTime split; PRMJTime split;
if (!MOZ_DOUBLE_IS_FINITE(date)) { if (!IsFinite(date)) {
JS_snprintf(buf, sizeof buf, js_NaN_date_str); JS_snprintf(buf, sizeof buf, js_NaN_date_str);
} else { } else {
JS_ASSERT(TimeClip(date) == date); JS_ASSERT(TimeClip(date) == date);
@ -2752,7 +2754,7 @@ ToLocaleFormatHelper(JSContext *cx, HandleObject obj, const char *format, Mutabl
double utctime = obj->getDateUTCTime().toNumber(); double utctime = obj->getDateUTCTime().toNumber();
char buf[100]; char buf[100];
if (!MOZ_DOUBLE_IS_FINITE(utctime)) { if (!IsFinite(utctime)) {
JS_snprintf(buf, sizeof buf, js_NaN_date_str); JS_snprintf(buf, sizeof buf, js_NaN_date_str);
} else { } else {
int result_len; int result_len;
@ -3120,7 +3122,7 @@ js_Date(JSContext *cx, unsigned argc, Value *vp)
if (!date_msecFromArgs(cx, args, &msec_time)) if (!date_msecFromArgs(cx, args, &msec_time))
return false; return false;
if (MOZ_DOUBLE_IS_FINITE(msec_time)) { if (IsFinite(msec_time)) {
msec_time = UTC(msec_time, &cx->runtime->dateTimeInfo); msec_time = UTC(msec_time, &cx->runtime->dateTimeInfo);
msec_time = TimeClip(msec_time); msec_time = TimeClip(msec_time);
} }
@ -3203,7 +3205,7 @@ js_NewDateObject(JSContext *cx, int year, int mon, int mday,
JS_FRIEND_API(JSBool) JS_FRIEND_API(JSBool)
js_DateIsValid(JSObject *obj) js_DateIsValid(JSObject *obj)
{ {
return obj->isDate() && !MOZ_DOUBLE_IS_NaN(obj->getDateUTCTime().toNumber()); return obj->isDate() && !IsNaN(obj->getDateUTCTime().toNumber());
} }
JS_FRIEND_API(int) JS_FRIEND_API(int)
@ -3212,7 +3214,7 @@ js_DateGetYear(JSContext *cx, JSObject *obj)
/* Preserve legacy API behavior of returning 0 for invalid dates. */ /* Preserve legacy API behavior of returning 0 for invalid dates. */
JS_ASSERT(obj); JS_ASSERT(obj);
double localtime = GetCachedLocalTime(&cx->runtime->dateTimeInfo, obj); double localtime = GetCachedLocalTime(&cx->runtime->dateTimeInfo, obj);
if (MOZ_DOUBLE_IS_NaN(localtime)) if (IsNaN(localtime))
return 0; return 0;
return (int) YearFromTime(localtime); return (int) YearFromTime(localtime);
@ -3223,7 +3225,7 @@ js_DateGetMonth(JSContext *cx, JSObject *obj)
{ {
JS_ASSERT(obj); JS_ASSERT(obj);
double localtime = GetCachedLocalTime(&cx->runtime->dateTimeInfo, obj); double localtime = GetCachedLocalTime(&cx->runtime->dateTimeInfo, obj);
if (MOZ_DOUBLE_IS_NaN(localtime)) if (IsNaN(localtime))
return 0; return 0;
return (int) MonthFromTime(localtime); return (int) MonthFromTime(localtime);
@ -3234,7 +3236,7 @@ js_DateGetDate(JSContext *cx, JSObject *obj)
{ {
JS_ASSERT(obj); JS_ASSERT(obj);
double localtime = GetCachedLocalTime(&cx->runtime->dateTimeInfo, obj); double localtime = GetCachedLocalTime(&cx->runtime->dateTimeInfo, obj);
if (MOZ_DOUBLE_IS_NaN(localtime)) if (IsNaN(localtime))
return 0; return 0;
return (int) DateFromTime(localtime); return (int) DateFromTime(localtime);
@ -3245,7 +3247,7 @@ js_DateGetHours(JSContext *cx, JSObject *obj)
{ {
JS_ASSERT(obj); JS_ASSERT(obj);
double localtime = GetCachedLocalTime(&cx->runtime->dateTimeInfo, obj); double localtime = GetCachedLocalTime(&cx->runtime->dateTimeInfo, obj);
if (MOZ_DOUBLE_IS_NaN(localtime)) if (IsNaN(localtime))
return 0; return 0;
return (int) HourFromTime(localtime); return (int) HourFromTime(localtime);
@ -3256,7 +3258,7 @@ js_DateGetMinutes(JSContext *cx, JSObject *obj)
{ {
JS_ASSERT(obj); JS_ASSERT(obj);
double localtime = GetCachedLocalTime(&cx->runtime->dateTimeInfo, obj); double localtime = GetCachedLocalTime(&cx->runtime->dateTimeInfo, obj);
if (MOZ_DOUBLE_IS_NaN(localtime)) if (IsNaN(localtime))
return 0; return 0;
return (int) MinFromTime(localtime); return (int) MinFromTime(localtime);
@ -3269,7 +3271,7 @@ js_DateGetSeconds(JSObject *obj)
return 0; return 0;
double utctime = obj->getDateUTCTime().toNumber(); double utctime = obj->getDateUTCTime().toNumber();
if (MOZ_DOUBLE_IS_NaN(utctime)) if (IsNaN(utctime))
return 0; return 0;
return (int) SecFromTime(utctime); return (int) SecFromTime(utctime);
} }

View File

@ -727,13 +727,13 @@ js::StrictlyEqual(JSContext *cx, const Value &lref, const Value &rref, bool *equ
static inline bool static inline bool
IsNegativeZero(const Value &v) IsNegativeZero(const Value &v)
{ {
return v.isDouble() && MOZ_DOUBLE_IS_NEGATIVE_ZERO(v.toDouble()); return v.isDouble() && mozilla::IsNegativeZero(v.toDouble());
} }
static inline bool static inline bool
IsNaN(const Value &v) IsNaN(const Value &v)
{ {
return v.isDouble() && MOZ_DOUBLE_IS_NaN(v.toDouble()); return v.isDouble() && mozilla::IsNaN(v.toDouble());
} }
bool bool
@ -2633,7 +2633,7 @@ BEGIN_CASE(JSOP_TABLESWITCH)
i = rref.toInt32(); i = rref.toInt32();
} else { } else {
double d; double d;
/* Don't use MOZ_DOUBLE_IS_INT32; treat -0 (double) as 0. */ /* Don't use mozilla::DoubleIsInt32; treat -0 (double) as 0. */
if (!rref.isDouble() || (d = rref.toDouble()) != (i = int32_t(rref.toDouble()))) if (!rref.isDouble() || (d = rref.toDouble()) != (i = int32_t(rref.toDouble())))
DO_NEXT_OP(len); DO_NEXT_OP(len);
} }

View File

@ -40,8 +40,8 @@ js_fmod(double d, double d2)
* Workaround MS fmod bug where 42 % (1/0) => NaN, not 42. * Workaround MS fmod bug where 42 % (1/0) => NaN, not 42.
* Workaround MS fmod bug where -0 % -N => 0, not -0. * Workaround MS fmod bug where -0 % -N => 0, not -0.
*/ */
if ((MOZ_DOUBLE_IS_FINITE(d) && MOZ_DOUBLE_IS_INFINITE(d2)) || if ((mozilla::IsFinite(d) && mozilla::IsInfinite(d2)) ||
(d == 0 && MOZ_DOUBLE_IS_FINITE(d2))) { (d == 0 && mozilla::IsFinite(d2))) {
return d; return d;
} }
#endif #endif
@ -54,14 +54,14 @@ inline double
NumberDiv(double a, double b) NumberDiv(double a, double b)
{ {
if (b == 0) { if (b == 0) {
if (a == 0 || MOZ_DOUBLE_IS_NaN(a) if (a == 0 || mozilla::IsNaN(a)
#ifdef XP_WIN #ifdef XP_WIN
|| MOZ_DOUBLE_IS_NaN(b) /* XXX MSVC miscompiles such that (NaN == 0) */ || mozilla::IsNaN(b) /* XXX MSVC miscompiles such that (NaN == 0) */
#endif #endif
) )
return js_NaN; return js_NaN;
if (MOZ_DOUBLE_IS_NEGATIVE(a) != MOZ_DOUBLE_IS_NEGATIVE(b)) if (mozilla::IsNegative(a) != mozilla::IsNegative(b))
return js_NegativeInfinity; return js_NegativeInfinity;
return js_PositiveInfinity; return js_PositiveInfinity;
} }

View File

@ -29,6 +29,16 @@
using namespace js; using namespace js;
using mozilla::Abs; using mozilla::Abs;
using mozilla::DoubleIsInt32;
using mozilla::ExponentComponent;
using mozilla::IsFinite;
using mozilla::IsInfinite;
using mozilla::IsNaN;
using mozilla::IsNegative;
using mozilla::IsNegativeZero;
using mozilla::PositiveInfinity;
using mozilla::NegativeInfinity;
using mozilla::SpecificNaN;
#ifndef M_E #ifndef M_E
#define M_E 2.7182818284590452354 #define M_E 2.7182818284590452354
@ -68,8 +78,8 @@ MathCache::MathCache() {
memset(table, 0, sizeof(table)); memset(table, 0, sizeof(table));
/* See comments in lookup(). */ /* See comments in lookup(). */
JS_ASSERT(MOZ_DOUBLE_IS_NEGATIVE_ZERO(-0.0)); JS_ASSERT(IsNegativeZero(-0.0));
JS_ASSERT(!MOZ_DOUBLE_IS_NEGATIVE_ZERO(+0.0)); JS_ASSERT(!IsNegativeZero(+0.0));
JS_ASSERT(hash(-0.0) != hash(+0.0)); JS_ASSERT(hash(-0.0) != hash(+0.0));
} }
@ -201,7 +211,7 @@ js::ecmaAtan2(double x, double y)
* - The sign of x determines the sign of the result. * - The sign of x determines the sign of the result.
* - The sign of y determines the multiplicator, 1 or 3. * - The sign of y determines the multiplicator, 1 or 3.
*/ */
if (MOZ_DOUBLE_IS_INFINITE(x) && MOZ_DOUBLE_IS_INFINITE(y)) { if (IsInfinite(x) && IsInfinite(y)) {
double z = js_copysign(M_PI / 4, x); double z = js_copysign(M_PI / 4, x);
if (y < 0) if (y < 0)
z *= 3; z *= 3;
@ -291,7 +301,7 @@ double
js::math_exp_impl(MathCache *cache, double x) js::math_exp_impl(MathCache *cache, double x)
{ {
#ifdef _WIN32 #ifdef _WIN32
if (!MOZ_DOUBLE_IS_NaN(x)) { if (!IsNaN(x)) {
if (x == js_PositiveInfinity) if (x == js_PositiveInfinity)
return js_PositiveInfinity; return js_PositiveInfinity;
if (x == js_NegativeInfinity) if (x == js_NegativeInfinity)
@ -395,12 +405,12 @@ js_math_max(JSContext *cx, unsigned argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp); CallArgs args = CallArgsFromVp(argc, vp);
double x; double x;
double maxval = MOZ_DOUBLE_NEGATIVE_INFINITY(); double maxval = NegativeInfinity();
for (unsigned i = 0; i < args.length(); i++) { for (unsigned i = 0; i < args.length(); i++) {
if (!ToNumber(cx, args[i], &x)) if (!ToNumber(cx, args[i], &x))
return false; return false;
// Math.max(num, NaN) => NaN, Math.max(-0, +0) => +0 // Math.max(num, NaN) => NaN, Math.max(-0, +0) => +0
if (x > maxval || MOZ_DOUBLE_IS_NaN(x) || (x == maxval && MOZ_DOUBLE_IS_NEGATIVE(maxval))) if (x > maxval || IsNaN(x) || (x == maxval && IsNegative(maxval)))
maxval = x; maxval = x;
} }
args.rval().setNumber(maxval); args.rval().setNumber(maxval);
@ -413,12 +423,12 @@ js_math_min(JSContext *cx, unsigned argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp); CallArgs args = CallArgsFromVp(argc, vp);
double x; double x;
double minval = MOZ_DOUBLE_POSITIVE_INFINITY(); double minval = PositiveInfinity();
for (unsigned i = 0; i < args.length(); i++) { for (unsigned i = 0; i < args.length(); i++) {
if (!ToNumber(cx, args[i], &x)) if (!ToNumber(cx, args[i], &x))
return false; return false;
// Math.min(num, NaN) => NaN, Math.min(-0, +0) => -0 // Math.min(num, NaN) => NaN, Math.min(-0, +0) => -0
if (x < minval || MOZ_DOUBLE_IS_NaN(x) || (x == minval && MOZ_DOUBLE_IS_NEGATIVE_ZERO(x))) if (x < minval || IsNaN(x) || (x == minval && IsNegativeZero(x)))
minval = x; minval = x;
} }
args.rval().setNumber(minval); args.rval().setNumber(minval);
@ -446,7 +456,7 @@ js::powi(double x, int y)
// given us a finite p. This happens very rarely. // given us a finite p. This happens very rarely.
double result = 1.0 / p; double result = 1.0 / p;
return (result == 0 && MOZ_DOUBLE_IS_INFINITE(p)) return (result == 0 && IsInfinite(p))
? pow(x, static_cast<double>(y)) // Avoid pow(double, int). ? pow(x, static_cast<double>(y)) // Avoid pow(double, int).
: result; : result;
} }
@ -478,7 +488,7 @@ js::ecmaPow(double x, double y)
* Because C99 and ECMA specify different behavior for pow(), * Because C99 and ECMA specify different behavior for pow(),
* we need to wrap the libm call to make it ECMA compliant. * we need to wrap the libm call to make it ECMA compliant.
*/ */
if (!MOZ_DOUBLE_IS_FINITE(y) && (x == 1.0 || x == -1.0)) if (!IsFinite(y) && (x == 1.0 || x == -1.0))
return js_NaN; return js_NaN;
/* pow(x, +-0) is always 1, even for x = NaN (MSVC gets this wrong). */ /* pow(x, +-0) is always 1, even for x = NaN (MSVC gets this wrong). */
if (y == 0) if (y == 0)
@ -508,7 +518,7 @@ js_math_pow(JSContext *cx, unsigned argc, Value *vp)
* Special case for square roots. Note that pow(x, 0.5) != sqrt(x) * Special case for square roots. Note that pow(x, 0.5) != sqrt(x)
* when x = -0.0, so we have to guard for this. * when x = -0.0, so we have to guard for this.
*/ */
if (MOZ_DOUBLE_IS_FINITE(x) && x != 0.0) { if (IsFinite(x) && x != 0.0) {
if (y == 0.5) { if (y == 0.5) {
vp->setNumber(sqrt(x)); vp->setNumber(sqrt(x));
return JS_TRUE; return JS_TRUE;
@ -607,13 +617,13 @@ js_math_round(JSContext *cx, unsigned argc, Value *vp)
return false; return false;
int32_t i; int32_t i;
if (MOZ_DOUBLE_IS_INT32(x, &i)) { if (DoubleIsInt32(x, &i)) {
args.rval().setInt32(i); args.rval().setInt32(i);
return true; return true;
} }
/* Some numbers are so big that adding 0.5 would give the wrong number */ /* Some numbers are so big that adding 0.5 would give the wrong number. */
if (MOZ_DOUBLE_EXPONENT(x) >= 52) { if (ExponentComponent(x) >= 52) {
args.rval().setNumber(x); args.rval().setNumber(x);
return true; return true;
} }

View File

@ -230,7 +230,7 @@ num_isNaN(JSContext *cx, unsigned argc, Value *vp)
double x; double x;
if (!ToNumber(cx, vp[2], &x)) if (!ToNumber(cx, vp[2], &x))
return false; return false;
vp->setBoolean(MOZ_DOUBLE_IS_NaN(x)); vp->setBoolean(mozilla::IsNaN(x));
return JS_TRUE; return JS_TRUE;
} }
@ -244,7 +244,7 @@ num_isFinite(JSContext *cx, unsigned argc, Value *vp)
double x; double x;
if (!ToNumber(cx, vp[2], &x)) if (!ToNumber(cx, vp[2], &x))
return JS_FALSE; return JS_FALSE;
vp->setBoolean(MOZ_DOUBLE_IS_FINITE(x)); vp->setBoolean(mozilla::IsFinite(x));
return JS_TRUE; return JS_TRUE;
} }
@ -911,7 +911,7 @@ Number_isNaN(JSContext *cx, unsigned argc, Value *vp)
args.rval().setBoolean(false); args.rval().setBoolean(false);
return true; return true;
} }
args.rval().setBoolean(MOZ_DOUBLE_IS_NaN(args[0].toDouble())); args.rval().setBoolean(mozilla::IsNaN(args[0].toDouble()));
return true; return true;
} }
@ -925,7 +925,7 @@ Number_isFinite(JSContext *cx, unsigned argc, Value *vp)
return true; return true;
} }
args.rval().setBoolean(args[0].isInt32() || args.rval().setBoolean(args[0].isInt32() ||
MOZ_DOUBLE_IS_FINITE(args[0].toDouble())); mozilla::IsFinite(args[0].toDouble()));
return true; return true;
} }
@ -940,7 +940,7 @@ Number_isInteger(JSContext *cx, unsigned argc, Value *vp)
} }
Value val = args[0]; Value val = args[0];
args.rval().setBoolean(val.isInt32() || args.rval().setBoolean(val.isInt32() ||
(MOZ_DOUBLE_IS_FINITE(val.toDouble()) && (mozilla::IsFinite(val.toDouble()) &&
ToInteger(val.toDouble()) == val.toDouble())); ToInteger(val.toDouble()) == val.toDouble()));
return true; return true;
} }
@ -1031,19 +1031,19 @@ js::InitRuntimeNumberState(JSRuntime *rt)
* Our NaN must be one particular canonical value, because we rely on NaN * Our NaN must be one particular canonical value, because we rely on NaN
* encoding for our value representation. See Value.h. * encoding for our value representation. See Value.h.
*/ */
d = MOZ_DOUBLE_SPECIFIC_NaN(0, 0x8000000000000ULL); d = mozilla::SpecificNaN(0, 0x8000000000000ULL);
number_constants[NC_NaN].dval = js_NaN = d; number_constants[NC_NaN].dval = js_NaN = d;
rt->NaNValue.setDouble(d); rt->NaNValue.setDouble(d);
d = MOZ_DOUBLE_POSITIVE_INFINITY(); d = mozilla::PositiveInfinity();
number_constants[NC_POSITIVE_INFINITY].dval = js_PositiveInfinity = d; number_constants[NC_POSITIVE_INFINITY].dval = js_PositiveInfinity = d;
rt->positiveInfinityValue.setDouble(d); rt->positiveInfinityValue.setDouble(d);
d = MOZ_DOUBLE_NEGATIVE_INFINITY(); d = mozilla::NegativeInfinity();
number_constants[NC_NEGATIVE_INFINITY].dval = js_NegativeInfinity = d; number_constants[NC_NEGATIVE_INFINITY].dval = js_NegativeInfinity = d;
rt->negativeInfinityValue.setDouble(d); rt->negativeInfinityValue.setDouble(d);
number_constants[NC_MIN_VALUE].dval = MOZ_DOUBLE_MIN_VALUE(); number_constants[NC_MIN_VALUE].dval = mozilla::MinDoubleValue();
// XXX If ENABLE_INTL_API becomes true all the time at some point, // XXX If ENABLE_INTL_API becomes true all the time at some point,
// js::InitRuntimeNumberState is no longer fallible, and we should // js::InitRuntimeNumberState is no longer fallible, and we should
@ -1171,7 +1171,7 @@ FracNumberToCString(JSContext *cx, ToCStringBuf *cbuf, double d, int base = 10)
#ifdef DEBUG #ifdef DEBUG
{ {
int32_t _; int32_t _;
JS_ASSERT(!MOZ_DOUBLE_IS_INT32(d, &_)); JS_ASSERT(!mozilla::DoubleIsInt32(d, &_));
} }
#endif #endif
@ -1199,7 +1199,7 @@ char *
js::NumberToCString(JSContext *cx, ToCStringBuf *cbuf, double d, int base/* = 10*/) js::NumberToCString(JSContext *cx, ToCStringBuf *cbuf, double d, int base/* = 10*/)
{ {
int32_t i; int32_t i;
return MOZ_DOUBLE_IS_INT32(d, &i) return mozilla::DoubleIsInt32(d, &i)
? IntToCString(cbuf, i, base) ? IntToCString(cbuf, i, base)
: FracNumberToCString(cx, cbuf, d, base); : FracNumberToCString(cx, cbuf, d, base);
} }
@ -1222,7 +1222,7 @@ js_NumberToStringWithBase(JSContext *cx, double d, int base)
JSCompartment *c = cx->compartment; JSCompartment *c = cx->compartment;
int32_t i; int32_t i;
if (MOZ_DOUBLE_IS_INT32(d, &i)) { if (mozilla::DoubleIsInt32(d, &i)) {
if (base == 10 && StaticStrings::hasInt(i)) if (base == 10 && StaticStrings::hasInt(i))
return cx->runtime->staticStrings.getInt(i); return cx->runtime->staticStrings.getInt(i);
if (unsigned(i) < unsigned(base)) { if (unsigned(i) < unsigned(base)) {
@ -1476,7 +1476,7 @@ js::ToUint16Slow(JSContext *cx, const Value &v, uint16_t *out)
return false; return false;
} }
if (d == 0 || !MOZ_DOUBLE_IS_FINITE(d)) { if (d == 0 || !mozilla::IsFinite(d)) {
*out = 0; *out = 0;
return true; return true;
} }

View File

@ -177,7 +177,7 @@ ValueFitsInInt32(const Value &v, int32_t *pi)
*pi = v.toInt32(); *pi = v.toInt32();
return true; return true;
} }
return v.isDouble() && MOZ_DOUBLE_IS_INT32(v.toDouble(), pi); return v.isDouble() && mozilla::DoubleIsInt32(v.toDouble(), pi);
} }
/* /*
@ -198,7 +198,7 @@ IsDefinitelyIndex(const Value &v, uint32_t *indexp)
} }
int32_t i; int32_t i;
if (v.isDouble() && MOZ_DOUBLE_IS_INT32(v.toDouble(), &i) && i >= 0) { if (v.isDouble() && mozilla::DoubleIsInt32(v.toDouble(), &i) && i >= 0) {
*indexp = uint32_t(i); *indexp = uint32_t(i);
return true; return true;
} }

View File

@ -31,6 +31,7 @@ using namespace js;
using namespace js::gc; using namespace js::gc;
using namespace js::types; using namespace js::types;
using mozilla::IsFinite;
using mozilla::Maybe; using mozilla::Maybe;
Class js::JSONClass = { Class js::JSONClass = {
@ -545,7 +546,7 @@ Str(JSContext *cx, const Value &v, StringifyContext *scx)
/* Step 9. */ /* Step 9. */
if (v.isNumber()) { if (v.isNumber()) {
if (v.isDouble()) { if (v.isDouble()) {
if (!MOZ_DOUBLE_IS_FINITE(v.toDouble())) if (!IsFinite(v.toDouble()))
return scx->sb.append("null"); return scx->sb.append("null");
} }

View File

@ -63,6 +63,8 @@ using namespace js::types;
using namespace js::unicode; using namespace js::unicode;
using mozilla::CheckedInt; using mozilla::CheckedInt;
using mozilla::IsNaN;
using mozilla::IsNegativeZero;
using mozilla::PodCopy; using mozilla::PodCopy;
using mozilla::PodEqual; using mozilla::PodEqual;
@ -1286,7 +1288,7 @@ str_lastIndexOf(JSContext *cx, unsigned argc, Value *vp)
double d; double d;
if (!ToNumber(cx, args[1], &d)) if (!ToNumber(cx, args[1], &d))
return false; return false;
if (!MOZ_DOUBLE_IS_NaN(d)) { if (!IsNaN(d)) {
d = ToInteger(d); d = ToInteger(d);
if (d <= 0) if (d <= 0)
i = 0; i = 0;
@ -3726,7 +3728,7 @@ js::ValueToSource(JSContext *cx, const Value &v)
return js_QuoteString(cx, v.toString(), '"'); return js_QuoteString(cx, v.toString(), '"');
if (v.isPrimitive()) { if (v.isPrimitive()) {
/* Special case to preserve negative zero, _contra_ toString. */ /* Special case to preserve negative zero, _contra_ toString. */
if (v.isDouble() && MOZ_DOUBLE_IS_NEGATIVE_ZERO(v.toDouble())) { if (v.isDouble() && IsNegativeZero(v.toDouble())) {
/* NB: _ucNstr rather than _ucstr to indicate non-terminated. */ /* NB: _ucNstr rather than _ucstr to indicate non-terminated. */
static const jschar js_negzero_ucNstr[] = {'-', '0'}; static const jschar js_negzero_ucNstr[] = {'-', '0'};

View File

@ -45,6 +45,7 @@ using namespace js;
using namespace js::gc; using namespace js::gc;
using namespace js::types; using namespace js::types;
using mozilla::IsNaN;
using mozilla::PodCopy; using mozilla::PodCopy;
/* /*
@ -67,7 +68,7 @@ ValueIsLength(const Value &v, uint32_t *len)
if (v.isDouble()) { if (v.isDouble()) {
double d = v.toDouble(); double d = v.toDouble();
if (MOZ_DOUBLE_IS_NaN(d)) if (IsNaN(d))
return false; return false;
uint32_t length = uint32_t(d); uint32_t length = uint32_t(d);
@ -2267,7 +2268,7 @@ class TypedArrayTemplate
static NativeType static NativeType
nativeFromDouble(double d) nativeFromDouble(double d)
{ {
if (!ArrayTypeIsFloatingPoint() && JS_UNLIKELY(MOZ_DOUBLE_IS_NaN(d))) if (!ArrayTypeIsFloatingPoint() && JS_UNLIKELY(IsNaN(d)))
return NativeType(int32_t(0)); return NativeType(int32_t(0));
if (TypeIsFloatingPoint<NativeType>()) if (TypeIsFloatingPoint<NativeType>())
return NativeType(d); return NativeType(d);

View File

@ -58,6 +58,9 @@ using namespace js::types;
using namespace JSC; using namespace JSC;
using mozilla::DebugOnly; using mozilla::DebugOnly;
using mozilla::DoubleIsInt32;
using mozilla::IsNaN;
using mozilla::IsNegative;
void JS_FASTCALL void JS_FASTCALL
stubs::BindName(VMFrame &f, PropertyName *name_) stubs::BindName(VMFrame &f, PropertyName *name_)
@ -673,13 +676,13 @@ stubs::Div(VMFrame &f)
const Value *vp; const Value *vp;
#ifdef XP_WIN #ifdef XP_WIN
/* XXX MSVC miscompiles such that (NaN == 0) */ /* XXX MSVC miscompiles such that (NaN == 0) */
if (MOZ_DOUBLE_IS_NaN(d2)) if (IsNaN(d2))
vp = &rt->NaNValue; vp = &rt->NaNValue;
else else
#endif #endif
if (d1 == 0 || MOZ_DOUBLE_IS_NaN(d1)) if (d1 == 0 || IsNaN(d1))
vp = &rt->NaNValue; vp = &rt->NaNValue;
else if (MOZ_DOUBLE_IS_NEGATIVE(d1) != MOZ_DOUBLE_IS_NEGATIVE(d2)) else if (IsNegative(d1) != IsNegative(d2))
vp = &rt->negativeInfinityValue; vp = &rt->negativeInfinityValue;
else else
vp = &rt->positiveInfinityValue; vp = &rt->positiveInfinityValue;
@ -1301,7 +1304,7 @@ stubs::TableSwitch(VMFrame &f, jsbytecode *origPc)
if (d == 0) { if (d == 0) {
/* Treat -0 (double) as 0. */ /* Treat -0 (double) as 0. */
tableIdx = 0; tableIdx = 0;
} else if (!MOZ_DOUBLE_IS_INT32(d, &tableIdx)) { } else if (!DoubleIsInt32(d, &tableIdx)) {
goto finally; goto finally;
} }
} else { } else {

View File

@ -10,6 +10,8 @@
#include "jsutil.h" #include "jsutil.h"
using mozilla::UnspecifiedNaN;
static bool static bool
ComputeLocalTime(time_t local, struct tm *ptm) ComputeLocalTime(time_t local, struct tm *ptm)
{ {
@ -162,7 +164,7 @@ js::DateTimeInfo::DateTimeInfo()
{ {
// Set to a totally impossible TZA so that the comparison above will fail // Set to a totally impossible TZA so that the comparison above will fail
// and all fields will be properly initialized. // and all fields will be properly initialized.
localTZA_ = MOZ_DOUBLE_NaN(); localTZA_ = UnspecifiedNaN();
updateTimeZoneAdjustment(); updateTimeZoneAdjustment();
} }

View File

@ -46,7 +46,7 @@ inline double
TimeClip(double time) TimeClip(double time)
{ {
/* Steps 1-2. */ /* Steps 1-2. */
if (!MOZ_DOUBLE_IS_FINITE(time) || mozilla::Abs(time) > MaxTimeMagnitude) if (!mozilla::IsFinite(time) || mozilla::Abs(time) > MaxTimeMagnitude)
return js_NaN; return js_NaN;
/* Step 3. */ /* Step 3. */

View File

@ -135,7 +135,7 @@ ToIntWidth(double d)
#else #else
double twoWidth, twoWidthMin1; double twoWidth, twoWidthMin1;
if (!MOZ_DOUBLE_IS_FINITE(d)) if (!mozilla::IsFinite(d))
return 0; return 0;
/* FIXME: This relies on undefined behavior; see bug 667739. */ /* FIXME: This relies on undefined behavior; see bug 667739. */
@ -309,8 +309,8 @@ ToInteger(double d)
if (d == 0) if (d == 0)
return d; return d;
if (!MOZ_DOUBLE_IS_FINITE(d)) { if (!mozilla::IsFinite(d)) {
if (MOZ_DOUBLE_IS_NaN(d)) if (mozilla::IsNaN(d))
return 0; return 0;
return d; return d;
} }

View File

@ -244,9 +244,9 @@ def init_value(attribute):
return "0" return "0"
else: else:
if realtype.count("double") and attribute.defvalue == "Infinity": if realtype.count("double") and attribute.defvalue == "Infinity":
return "MOZ_DOUBLE_POSITIVE_INFINITY()" return "mozilla::PositiveInfinity()"
if realtype.count("double") and attribute.defvalue == "-Infinity": if realtype.count("double") and attribute.defvalue == "-Infinity":
return "MOZ_DOUBLE_NEGATIVE_INFINITY()" return "mozilla::NegativeInfinity()"
if realtype.count("nsAString"): if realtype.count("nsAString"):
return "NS_LITERAL_STRING(\"%s\")" % attribute.defvalue return "NS_LITERAL_STRING(\"%s\")" % attribute.defvalue
if realtype.count("nsACString"): if realtype.count("nsACString"):

View File

@ -42,7 +42,7 @@ nsCSSValue::nsCSSValue(float aValue, nsCSSUnit aUnit)
NS_ABORT_IF_FALSE(eCSSUnit_Percent <= aUnit, "not a float value"); NS_ABORT_IF_FALSE(eCSSUnit_Percent <= aUnit, "not a float value");
if (eCSSUnit_Percent <= aUnit) { if (eCSSUnit_Percent <= aUnit) {
mValue.mFloat = aValue; mValue.mFloat = aValue;
MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(mValue.mFloat)); MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
} }
else { else {
mUnit = eCSSUnit_Null; mUnit = eCSSUnit_Null;
@ -105,7 +105,7 @@ nsCSSValue::nsCSSValue(const nsCSSValue& aCopy)
} }
else if (eCSSUnit_Percent <= mUnit) { else if (eCSSUnit_Percent <= mUnit) {
mValue.mFloat = aCopy.mValue.mFloat; mValue.mFloat = aCopy.mValue.mFloat;
MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(mValue.mFloat)); MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
} }
else if (UnitHasStringValue()) { else if (UnitHasStringValue()) {
mValue.mString = aCopy.mValue.mString; mValue.mString = aCopy.mValue.mString;
@ -323,7 +323,7 @@ void nsCSSValue::SetPercentValue(float aValue)
Reset(); Reset();
mUnit = eCSSUnit_Percent; mUnit = eCSSUnit_Percent;
mValue.mFloat = aValue; mValue.mFloat = aValue;
MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(mValue.mFloat)); MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
} }
void nsCSSValue::SetFloatValue(float aValue, nsCSSUnit aUnit) void nsCSSValue::SetFloatValue(float aValue, nsCSSUnit aUnit)
@ -333,7 +333,7 @@ void nsCSSValue::SetFloatValue(float aValue, nsCSSUnit aUnit)
if (eCSSUnit_Number <= aUnit) { if (eCSSUnit_Number <= aUnit) {
mUnit = aUnit; mUnit = aUnit;
mValue.mFloat = aValue; mValue.mFloat = aValue;
MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(mValue.mFloat)); MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
} }
} }

View File

@ -9,6 +9,7 @@
#define nsCSSValue_h___ #define nsCSSValue_h___
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/FloatingPoint.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsCRTGlue.h" #include "nsCRTGlue.h"
@ -21,7 +22,6 @@
#include "nsStringBuffer.h" #include "nsStringBuffer.h"
#include "nsTArray.h" #include "nsTArray.h"
#include "nsStyleConsts.h" #include "nsStyleConsts.h"
#include "mozilla/FloatingPoint.h"
class imgRequestProxy; class imgRequestProxy;
class nsIDocument; class nsIDocument;
@ -355,7 +355,7 @@ public:
float GetFloatValue() const float GetFloatValue() const
{ {
NS_ABORT_IF_FALSE(eCSSUnit_Number <= mUnit, "not a float value"); NS_ABORT_IF_FALSE(eCSSUnit_Number <= mUnit, "not a float value");
MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(mValue.mFloat)); MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
return mValue.mFloat; return mValue.mFloat;
} }

View File

@ -883,13 +883,13 @@ MOZ_ALWAYS_INLINE float
EnsureNotNan(float aValue) EnsureNotNan(float aValue)
{ {
// This would benefit from a MOZ_FLOAT_IS_NaN if we had one. // This would benefit from a MOZ_FLOAT_IS_NaN if we had one.
return MOZ_LIKELY(!MOZ_DOUBLE_IS_NaN(aValue)) ? aValue : 0; return MOZ_LIKELY(!mozilla::IsNaN(aValue)) ? aValue : 0;
} }
template<> template<>
MOZ_ALWAYS_INLINE double MOZ_ALWAYS_INLINE double
EnsureNotNan(double aValue) EnsureNotNan(double aValue)
{ {
return MOZ_LIKELY(!MOZ_DOUBLE_IS_NaN(aValue)) ? aValue : 0; return MOZ_LIKELY(!mozilla::IsNaN(aValue)) ? aValue : 0;
} }
template <typename T> template <typename T>
@ -3219,14 +3219,14 @@ nsStyleAnimation::Value::Value(float aPercent, PercentConstructorType)
{ {
mUnit = eUnit_Percent; mUnit = eUnit_Percent;
mValue.mFloat = aPercent; mValue.mFloat = aPercent;
MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(mValue.mFloat)); MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
} }
nsStyleAnimation::Value::Value(float aFloat, FloatConstructorType) nsStyleAnimation::Value::Value(float aFloat, FloatConstructorType)
{ {
mUnit = eUnit_Float; mUnit = eUnit_Float;
mValue.mFloat = aFloat; mValue.mFloat = aFloat;
MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(mValue.mFloat)); MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
} }
nsStyleAnimation::Value::Value(nscolor aColor, ColorConstructorType) nsStyleAnimation::Value::Value(nscolor aColor, ColorConstructorType)
@ -3258,7 +3258,7 @@ nsStyleAnimation::Value::operator=(const Value& aOther)
case eUnit_Percent: case eUnit_Percent:
case eUnit_Float: case eUnit_Float:
mValue.mFloat = aOther.mValue.mFloat; mValue.mFloat = aOther.mValue.mFloat;
MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(mValue.mFloat)); MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
break; break;
case eUnit_Color: case eUnit_Color:
mValue.mColor = aOther.mValue.mColor; mValue.mColor = aOther.mValue.mColor;
@ -3370,7 +3370,7 @@ nsStyleAnimation::Value::SetPercentValue(float aPercent)
FreeValue(); FreeValue();
mUnit = eUnit_Percent; mUnit = eUnit_Percent;
mValue.mFloat = aPercent; mValue.mFloat = aPercent;
MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(mValue.mFloat)); MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
} }
void void
@ -3379,7 +3379,7 @@ nsStyleAnimation::Value::SetFloatValue(float aFloat)
FreeValue(); FreeValue();
mUnit = eUnit_Float; mUnit = eUnit_Float;
mValue.mFloat = aFloat; mValue.mFloat = aFloat;
MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(mValue.mFloat)); MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
} }
void void

View File

@ -12,6 +12,8 @@
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/StandardInteger.h" #include "mozilla/StandardInteger.h"
namespace mozilla {
/* /*
* It's reasonable to ask why we have this header at all. Don't isnan, * It's reasonable to ask why we have this header at all. Don't isnan,
* copysign, the built-in comparison operators, and the like solve these * copysign, the built-in comparison operators, and the like solve these
@ -25,10 +27,6 @@
* For the aforementioned reasons, be very wary of making changes to any of * For the aforementioned reasons, be very wary of making changes to any of
* these algorithms. If you must make changes, keep a careful eye out for * these algorithms. If you must make changes, keep a careful eye out for
* compiler bustage, particularly PGO-specific bustage. * compiler bustage, particularly PGO-specific bustage.
*
* Some users require that this file be C-compatible. Unfortunately, this means
* no mozilla namespace to contain everything, no detail namespace clarifying
* MozDoublePun to be an internal data structure, and so on.
*/ */
/* /*
@ -39,37 +37,28 @@
*/ */
MOZ_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t), "double must be 64 bits"); MOZ_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t), "double must be 64 bits");
/* const unsigned DoubleExponentBias = 1023;
* Constant expressions in C can't refer to consts, unfortunately, so #define const unsigned DoubleExponentShift = 52;
* these rather than use |const uint64_t|.
*/
#define MOZ_DOUBLE_SIGN_BIT 0x8000000000000000ULL
#define MOZ_DOUBLE_EXPONENT_BITS 0x7ff0000000000000ULL
#define MOZ_DOUBLE_SIGNIFICAND_BITS 0x000fffffffffffffULL
#define MOZ_DOUBLE_EXPONENT_BIAS 1023 namespace detail {
#define MOZ_DOUBLE_EXPONENT_SHIFT 52
MOZ_STATIC_ASSERT((MOZ_DOUBLE_SIGN_BIT & MOZ_DOUBLE_EXPONENT_BITS) == 0, const uint64_t DoubleSignBit = 0x8000000000000000ULL;
const uint64_t DoubleExponentBits = 0x7ff0000000000000ULL;
const uint64_t DoubleSignificandBits = 0x000fffffffffffffULL;
MOZ_STATIC_ASSERT((DoubleSignBit & DoubleExponentBits) == 0,
"sign bit doesn't overlap exponent bits"); "sign bit doesn't overlap exponent bits");
MOZ_STATIC_ASSERT((MOZ_DOUBLE_SIGN_BIT & MOZ_DOUBLE_SIGNIFICAND_BITS) == 0, MOZ_STATIC_ASSERT((DoubleSignBit & DoubleSignificandBits) == 0,
"sign bit doesn't overlap significand bits"); "sign bit doesn't overlap significand bits");
MOZ_STATIC_ASSERT((MOZ_DOUBLE_EXPONENT_BITS & MOZ_DOUBLE_SIGNIFICAND_BITS) == 0, MOZ_STATIC_ASSERT((DoubleExponentBits & DoubleSignificandBits) == 0,
"exponent bits don't overlap significand bits"); "exponent bits don't overlap significand bits");
MOZ_STATIC_ASSERT((MOZ_DOUBLE_SIGN_BIT | MOZ_DOUBLE_EXPONENT_BITS | MOZ_DOUBLE_SIGNIFICAND_BITS) MOZ_STATIC_ASSERT((DoubleSignBit | DoubleExponentBits | DoubleSignificandBits) ==
== ~(uint64_t)0, ~uint64_t(0),
"all bits accounted for"); "all bits accounted for");
#ifdef __cplusplus union DoublePun
extern "C" { {
#endif
/*
* This union is NOT a public data structure, and it is not to be used outside
* this file!
*/
union MozDoublePun {
/* /*
* Every way to pun the bits of a double introduces an additional layer of * Every way to pun the bits of a double introduces an additional layer of
* complexity, across a multitude of platforms, architectures, and ABIs. * complexity, across a multitude of platforms, architectures, and ABIs.
@ -80,165 +69,164 @@ union MozDoublePun {
double d; double d;
}; };
} /* namespace detail */
/** Determines whether a double is NaN. */ /** Determines whether a double is NaN. */
static MOZ_ALWAYS_INLINE int static MOZ_ALWAYS_INLINE bool
MOZ_DOUBLE_IS_NaN(double d) IsNaN(double d)
{ {
union MozDoublePun pun; union detail::DoublePun pun;
pun.d = d; pun.d = d;
/* /*
* A double is NaN if all exponent bits are 1 and the significand contains at * A double is NaN if all exponent bits are 1 and the significand contains at
* least one non-zero bit. * least one non-zero bit.
*/ */
return (pun.u & MOZ_DOUBLE_EXPONENT_BITS) == MOZ_DOUBLE_EXPONENT_BITS && return (pun.u & detail::DoubleExponentBits) == detail::DoubleExponentBits &&
(pun.u & MOZ_DOUBLE_SIGNIFICAND_BITS) != 0; (pun.u & detail::DoubleSignificandBits) != 0;
} }
/** Determines whether a double is +Infinity or -Infinity. */ /** Determines whether a double is +Infinity or -Infinity. */
static MOZ_ALWAYS_INLINE int static MOZ_ALWAYS_INLINE bool
MOZ_DOUBLE_IS_INFINITE(double d) IsInfinite(double d)
{ {
union MozDoublePun pun; union detail::DoublePun pun;
pun.d = d; pun.d = d;
/* Infinities have all exponent bits set to 1 and an all-0 significand. */ /* Infinities have all exponent bits set to 1 and an all-0 significand. */
return (pun.u & ~MOZ_DOUBLE_SIGN_BIT) == MOZ_DOUBLE_EXPONENT_BITS; return (pun.u & ~detail::DoubleSignBit) == detail::DoubleExponentBits;
} }
/** Determines whether a double is not NaN or infinite. */ /** Determines whether a double is not NaN or infinite. */
static MOZ_ALWAYS_INLINE int static MOZ_ALWAYS_INLINE bool
MOZ_DOUBLE_IS_FINITE(double d) IsFinite(double d)
{ {
union MozDoublePun pun; union detail::DoublePun pun;
pun.d = d; pun.d = d;
/* /*
* NaN and Infinities are the only non-finite doubles, and both have all * NaN and Infinities are the only non-finite doubles, and both have all
* exponent bits set to 1. * exponent bits set to 1.
*/ */
return (pun.u & MOZ_DOUBLE_EXPONENT_BITS) != MOZ_DOUBLE_EXPONENT_BITS; return (pun.u & detail::DoubleExponentBits) != detail::DoubleExponentBits;
} }
/** /**
* Determines whether a double is negative. It is an error to call this method * Determines whether a double is negative. It is an error to call this method
* on a double which is NaN. * on a double which is NaN.
*/ */
static MOZ_ALWAYS_INLINE int static MOZ_ALWAYS_INLINE bool
MOZ_DOUBLE_IS_NEGATIVE(double d) IsNegative(double d)
{ {
union MozDoublePun pun; MOZ_ASSERT(!IsNaN(d), "NaN does not have a sign");
union detail::DoublePun pun;
pun.d = d; pun.d = d;
MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(d), "NaN does not have a sign");
/* The sign bit is set if the double is negative. */ /* The sign bit is set if the double is negative. */
return (pun.u & MOZ_DOUBLE_SIGN_BIT) != 0; return (pun.u & detail::DoubleSignBit) != 0;
} }
/** Determines whether a double represents -0. */ /** Determines whether a double represents -0. */
static MOZ_ALWAYS_INLINE int static MOZ_ALWAYS_INLINE bool
MOZ_DOUBLE_IS_NEGATIVE_ZERO(double d) IsNegativeZero(double d)
{ {
union MozDoublePun pun; union detail::DoublePun pun;
pun.d = d; pun.d = d;
/* Only the sign bit is set if the double is -0. */ /* Only the sign bit is set if the double is -0. */
return pun.u == MOZ_DOUBLE_SIGN_BIT; return pun.u == detail::DoubleSignBit;
} }
/** Returns the exponent portion of the double. */ /** Returns the exponent portion of the double. */
static MOZ_ALWAYS_INLINE int_fast16_t static MOZ_ALWAYS_INLINE int_fast16_t
MOZ_DOUBLE_EXPONENT(double d) ExponentComponent(double d)
{ {
union MozDoublePun pun; union detail::DoublePun pun;
pun.d = d; pun.d = d;
/* /*
* The exponent component of a double is an unsigned number, biased from its * The exponent component of a double is an unsigned number, biased from its
* actual value. Subtract the bias to retrieve the actual exponent. * actual value. Subtract the bias to retrieve the actual exponent.
*/ */
return (int_fast16_t)((pun.u & MOZ_DOUBLE_EXPONENT_BITS) >> MOZ_DOUBLE_EXPONENT_SHIFT) - return int_fast16_t((pun.u & detail::DoubleExponentBits) >> DoubleExponentShift) -
MOZ_DOUBLE_EXPONENT_BIAS; int_fast16_t(DoubleExponentBias);
} }
/** Returns +Infinity. */ /** Returns +Infinity. */
static MOZ_ALWAYS_INLINE double static MOZ_ALWAYS_INLINE double
MOZ_DOUBLE_POSITIVE_INFINITY() PositiveInfinity()
{ {
union MozDoublePun pun; union detail::DoublePun pun;
/* /*
* Positive infinity has all exponent bits set, sign bit set to 0, and no * Positive infinity has all exponent bits set, sign bit set to 0, and no
* significand. * significand.
*/ */
pun.u = MOZ_DOUBLE_EXPONENT_BITS; pun.u = detail::DoubleExponentBits;
return pun.d; return pun.d;
} }
/** Returns -Infinity. */ /** Returns -Infinity. */
static MOZ_ALWAYS_INLINE double static MOZ_ALWAYS_INLINE double
MOZ_DOUBLE_NEGATIVE_INFINITY() NegativeInfinity()
{ {
union MozDoublePun pun; union detail::DoublePun pun;
/* /*
* Negative infinity has all exponent bits set, sign bit set to 1, and no * Negative infinity has all exponent bits set, sign bit set to 1, and no
* significand. * significand.
*/ */
pun.u = MOZ_DOUBLE_SIGN_BIT | MOZ_DOUBLE_EXPONENT_BITS; pun.u = detail::DoubleSignBit | detail::DoubleExponentBits;
return pun.d; return pun.d;
} }
/** Constructs a NaN value with the specified sign bit and significand bits. */ /** Constructs a NaN value with the specified sign bit and significand bits. */
static MOZ_ALWAYS_INLINE double static MOZ_ALWAYS_INLINE double
MOZ_DOUBLE_SPECIFIC_NaN(int signbit, uint64_t significand) SpecificNaN(int signbit, uint64_t significand)
{ {
union MozDoublePun pun;
MOZ_ASSERT(signbit == 0 || signbit == 1); MOZ_ASSERT(signbit == 0 || signbit == 1);
MOZ_ASSERT((significand & ~MOZ_DOUBLE_SIGNIFICAND_BITS) == 0); MOZ_ASSERT((significand & ~detail::DoubleSignificandBits) == 0);
MOZ_ASSERT(significand & MOZ_DOUBLE_SIGNIFICAND_BITS); MOZ_ASSERT(significand & detail::DoubleSignificandBits);
pun.u = (signbit ? MOZ_DOUBLE_SIGN_BIT : 0) | union detail::DoublePun pun;
MOZ_DOUBLE_EXPONENT_BITS | pun.u = (signbit ? detail::DoubleSignBit : 0) |
detail::DoubleExponentBits |
significand; significand;
MOZ_ASSERT(MOZ_DOUBLE_IS_NaN(pun.d)); MOZ_ASSERT(IsNaN(pun.d));
return pun.d; return pun.d;
} }
/** Computes the smallest non-zero positive double value. */
static MOZ_ALWAYS_INLINE double
MinDoubleValue()
{
union detail::DoublePun pun;
pun.u = 1;
return pun.d;
}
static MOZ_ALWAYS_INLINE bool
DoubleIsInt32(double d, int32_t* i)
{
/*
* XXX Casting a double that doesn't truncate to int32_t, to int32_t, induces
* undefined behavior. We should definitely fix this (bug 744965), but as
* apparently it "works" in practice, it's not a pressing concern now.
*/
return !IsNegativeZero(d) && d == (*i = int32_t(d));
}
/** /**
* Computes a NaN value. Do not use this method if you depend upon a particular * Computes a NaN value. Do not use this method if you depend upon a particular
* NaN value being returned. * NaN value being returned.
*/ */
static MOZ_ALWAYS_INLINE double static MOZ_ALWAYS_INLINE double
MOZ_DOUBLE_NaN() UnspecifiedNaN()
{ {
return MOZ_DOUBLE_SPECIFIC_NaN(0, 0xfffffffffffffULL); return mozilla::SpecificNaN(0, 0xfffffffffffffULL);
} }
/** Computes the smallest non-zero positive double value. */ } /* namespace mozilla */
static MOZ_ALWAYS_INLINE double
MOZ_DOUBLE_MIN_VALUE()
{
union MozDoublePun pun;
pun.u = 1;
return pun.d;
}
static MOZ_ALWAYS_INLINE int
MOZ_DOUBLE_IS_INT32(double d, int32_t* i)
{
/*
* XXX Casting a double that doesn't truncate to int32_t, to int32_t, induces
* undefined behavior. We should definitely fix this (bug 744965), but as
* apparently it "works" in practice, it's not a pressing concern now.
*/
return !MOZ_DOUBLE_IS_NEGATIVE_ZERO(d) && d == (*i = (int32_t)d);
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* mozilla_FloatingPoint_h_ */ #endif /* mozilla_FloatingPoint_h_ */

View File

@ -41,9 +41,9 @@
#if defined(_MSC_VER) && (_MSC_VER <= 1700) #if defined(_MSC_VER) && (_MSC_VER <= 1700)
namespace std { namespace std {
inline bool isinf(double num) { return MOZ_DOUBLE_IS_INFINITE(num); } inline bool isinf(double num) { return mozilla::IsInfinite(num); }
inline bool isnan(double num) { return MOZ_DOUBLE_IS_NaN(num); } inline bool isnan(double num) { return mozilla::IsNaN(num); }
inline bool isfinite(double num) { return MOZ_DOUBLE_IS_FINITE(num); } inline bool isfinite(double num) { return mozilla::IsFinite(num); }
} }
#endif #endif
@ -52,12 +52,12 @@ typedef std::string String;
double mozToDouble(const String &aStr, bool *valid) { double mozToDouble(const String &aStr, bool *valid) {
double_conversion::StringToDoubleConverter converter( double_conversion::StringToDoubleConverter converter(
double_conversion::StringToDoubleConverter::NO_FLAGS, double_conversion::StringToDoubleConverter::NO_FLAGS,
MOZ_DOUBLE_NaN(), MOZ_DOUBLE_NaN(), nullptr, nullptr); mozilla::UnspecifiedNaN(), mozilla::UnspecifiedNaN(), nullptr, nullptr);
const char* str = aStr.c_str(); const char* str = aStr.c_str();
int length = mozilla::SafeCast<int>(strlen(str)); int length = mozilla::SafeCast<int>(strlen(str));
int processed_char_count; // unused - NO_FLAGS requires the whole string to parse int processed_char_count; // unused - NO_FLAGS requires the whole string to parse
double result = converter.StringToDouble(str, length, &processed_char_count); double result = converter.StringToDouble(str, length, &processed_char_count);
*valid = MOZ_DOUBLE_IS_FINITE(result); *valid = mozilla::IsFinite(result);
return result; return result;
} }