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

View File

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

View File

@ -130,7 +130,7 @@ struct AudioTimelineEvent {
private:
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)
{
MOZ_ASSERT(NS_IsMainThread());
if (MOZ_DOUBLE_IS_INFINITE(aDuration)) {
if (mozilla::IsInfinite(aDuration)) {
SetInfinite(true);
} else if (MOZ_DOUBLE_IS_NaN(aDuration)) {
} else if (IsNaN(aDuration)) {
mDuration = -1;
SetInfinite(true);
} else {

View File

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

View File

@ -37,6 +37,8 @@
using namespace std;
using mozilla::dom::WebAudioUtils;
using mozilla::IsInfinite;
using mozilla::IsNaN;
namespace WebCore {
@ -285,9 +287,9 @@ void DynamicsCompressorKernel::process(float* sourceChannels[],
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Fix gremlins.
if (MOZ_DOUBLE_IS_NaN(m_detectorAverage))
if (IsNaN(m_detectorAverage))
m_detectorAverage = 1;
if (MOZ_DOUBLE_IS_INFINITE(m_detectorAverage))
if (IsInfinite(m_detectorAverage))
m_detectorAverage = 1;
float desiredGain = m_detectorAverage;
@ -313,9 +315,9 @@ void DynamicsCompressorKernel::process(float* sourceChannels[],
m_maxAttackCompressionDiffDb = -1;
// Fix gremlins.
if (MOZ_DOUBLE_IS_NaN(compressionDiffDb))
if (IsNaN(compressionDiffDb))
compressionDiffDb = -1;
if (MOZ_DOUBLE_IS_INFINITE(compressionDiffDb))
if (IsInfinite(compressionDiffDb))
compressionDiffDb = -1;
// Adaptive release - higher compression (lower compressionDiffDb) releases faster.
@ -341,9 +343,9 @@ void DynamicsCompressorKernel::process(float* sourceChannels[],
// Attack mode - compressionDiffDb should be positive dB
// Fix gremlins.
if (MOZ_DOUBLE_IS_NaN(compressionDiffDb))
if (IsNaN(compressionDiffDb))
compressionDiffDb = 1;
if (MOZ_DOUBLE_IS_INFINITE(compressionDiffDb))
if (IsInfinite(compressionDiffDb))
compressionDiffDb = 1;
// 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);
// Fix gremlins.
if (MOZ_DOUBLE_IS_NaN(detectorAverage))
if (IsNaN(detectorAverage))
detectorAverage = 1;
if (MOZ_DOUBLE_IS_INFINITE(detectorAverage))
if (IsInfinite(detectorAverage))
detectorAverage = 1;
// Exponential approach to desired gain.

View File

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

View File

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

View File

@ -39,16 +39,16 @@ txNumberExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
if (rightDbl == 0) {
#if defined(XP_WIN)
/* XXX MSVC miscompiles such that (NaN == 0) */
if (MOZ_DOUBLE_IS_NaN(rightDbl))
result = MOZ_DOUBLE_NaN();
if (mozilla::IsNaN(rightDbl))
result = mozilla::UnspecifiedNaN();
else
#endif
if (leftDbl == 0 || MOZ_DOUBLE_IS_NaN(leftDbl))
result = MOZ_DOUBLE_NaN();
else if (MOZ_DOUBLE_IS_NEGATIVE(leftDbl) ^ MOZ_DOUBLE_IS_NEGATIVE(rightDbl))
result = MOZ_DOUBLE_NEGATIVE_INFINITY();
if (leftDbl == 0 || mozilla::IsNaN(leftDbl))
result = mozilla::UnspecifiedNaN();
else if (mozilla::IsNegative(leftDbl) != mozilla::IsNegative(rightDbl))
result = mozilla::NegativeInfinity();
else
result = MOZ_DOUBLE_POSITIVE_INFINITY();
result = mozilla::PositiveInfinity();
}
else
result = leftDbl / rightDbl;
@ -56,12 +56,12 @@ txNumberExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
case MODULUS:
if (rightDbl == 0) {
result = MOZ_DOUBLE_NaN();
result = mozilla::UnspecifiedNaN();
}
else {
#if defined(XP_WIN)
/* 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;
else
#endif

View File

@ -49,7 +49,7 @@ bool NumberResult::booleanValue() {
// OG+
// 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
return (bool)(value != 0.0 && !MOZ_DOUBLE_IS_NaN(value));
return (bool)(value != 0.0 && !mozilla::IsNaN(value));
// OG-
} //-- booleanValue

View File

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

View File

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

View File

@ -81,16 +81,16 @@ txFormatNumberFunctionCall::evaluate(txIEvalContext* aContext,
}
// Special cases
if (MOZ_DOUBLE_IS_NaN(value)) {
if (mozilla::IsNaN(value)) {
return aContext->recycler()->getStringResult(format->mNaN, aResult);
}
if (value == MOZ_DOUBLE_POSITIVE_INFINITY()) {
if (value == mozilla::PositiveInfinity()) {
return aContext->recycler()->getStringResult(format->mInfinity,
aResult);
}
if (value == MOZ_DOUBLE_NEGATIVE_INFINITY()) {
if (value == mozilla::NegativeInfinity()) {
nsAutoString res;
res.Append(format->mMinusSign);
res.Append(format->mInfinity);
@ -112,7 +112,7 @@ txFormatNumberFunctionCall::evaluate(txIEvalContext* aContext,
// Get right subexpression
inQuote = false;
if (MOZ_DOUBLE_IS_NEGATIVE(value)) {
if (mozilla::IsNegative(value)) {
while (pos < formatLen &&
(inQuote ||
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
while (simple) {
double priority = aTemplate->mPrio;
if (MOZ_DOUBLE_IS_NaN(priority)) {
if (mozilla::IsNaN(priority)) {
priority = simple->getDefaultPriority();
NS_ASSERTION(!MOZ_DOUBLE_IS_NaN(priority),
NS_ASSERTION(!mozilla::IsNaN(priority),
"simple pattern without default priority");
}

View File

@ -271,7 +271,7 @@ getNumberAttr(txStylesheetAttr* aAttributes,
txStylesheetCompilerState& aState,
double& aNumber)
{
aNumber = MOZ_DOUBLE_NaN();
aNumber = UnspecifiedNaN();
txStylesheetAttr* attr = nullptr;
nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
aName, aRequired, &attr);
@ -280,7 +280,7 @@ getNumberAttr(txStylesheetAttr* aAttributes,
}
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
return NS_ERROR_XSLT_PARSE_FAILURE;
}
@ -520,7 +520,7 @@ txFnStartLREStylesheet(int32_t aNamespaceID,
NS_ENSURE_SUCCESS(rv, rv);
txExpandedName nullExpr;
double prio = MOZ_DOUBLE_NaN();
double prio = UnspecifiedNaN();
nsAutoPtr<txPattern> match(new txRootPattern());
NS_ENSURE_TRUE(match, NS_ERROR_OUT_OF_MEMORY);
@ -1113,7 +1113,7 @@ txFnStartTemplate(int32_t aNamespaceID,
aState, mode);
NS_ENSURE_SUCCESS(rv, rv);
double prio = MOZ_DOUBLE_NaN();
double prio = UnspecifiedNaN();
rv = getNumberAttr(aAttributes, aAttrCount, nsGkAtoms::priority,
false, aState, prio);
NS_ENSURE_SUCCESS(rv, rv);

View File

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

View File

@ -91,7 +91,7 @@ txXSLTNumber::getValueList(Expr* aValueExpr, txPattern* aCountPattern,
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) {
txDouble::toString(value, aValueString);
return NS_OK;

View File

@ -23,7 +23,7 @@
double txUnionPattern::getDefaultPriority()
{
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::Date() :
mMsecSinceEpoch(MOZ_DOUBLE_NaN())
mMsecSinceEpoch(UnspecifiedNaN())
{
}
bool
Date::IsUndefined() const
{
return MOZ_DOUBLE_IS_NaN(mMsecSinceEpoch);
return IsNaN(mMsecSinceEpoch);
}
bool

View File

@ -2256,11 +2256,11 @@ def numericValue(t, v):
if (t == IDLType.Tags.unrestricted_double or
t == IDLType.Tags.unrestricted_float):
if v == float("inf"):
return "MOZ_DOUBLE_POSITIVE_INFINITY()"
return "mozilla::PositiveInfinity()"
if v == float("-inf"):
return "MOZ_DOUBLE_NEGATIVE_INFINITY()"
return "mozilla::NegativeInfinity()"
if math.isnan(v):
return "MOZ_DOUBLE_NaN()"
return "mozilla::UnspecifiedNaN()"
return "%s%s" % (v, numericSuffixes[t])
class CastableObjectUnwrapper():
@ -3393,8 +3393,8 @@ for (uint32_t i = 0; i < length; ++i) {
else:
nonFiniteCode = (" ThrowErrorMessage(cx, MSG_NOT_FINITE);\n"
"%s" % exceptionCodeIndented.define())
template += (" else if (!MOZ_DOUBLE_IS_FINITE(%s)) {\n"
" // Note: MOZ_DOUBLE_IS_FINITE will do the right thing\n"
template += (" else if (!mozilla::IsFinite(%s)) {\n"
" // Note: mozilla::IsFinite will do the right thing\n"
" // when passed a non-finite float too.\n"
"%s\n"
"}" % (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,
"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());
}
@ -251,7 +251,7 @@ PrimitiveConversionTraits_Clamp(JSContext* cx, const double& d, T* retval)
MOZ_STATIC_ASSERT(std::numeric_limits<T>::is_integer,
"This can only be applied to integers!");
if (MOZ_DOUBLE_IS_NaN(d)) {
if (mozilla::IsNaN(d)) {
*retval = 0;
return true;
}
@ -264,7 +264,7 @@ PrimitiveConversionTraits_Clamp(JSContext* cx, const double& d, T* retval)
return true;
}
MOZ_ASSERT(MOZ_DOUBLE_IS_FINITE(d));
MOZ_ASSERT(mozilla::IsFinite(d));
// Banker's rounding (round ties towards even).
// 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)) {
double d = JSVAL_TO_DOUBLE(aVal);
if (MOZ_DOUBLE_IS_NaN(d)) {
if (mozilla::IsNaN(d)) {
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
}
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),
style(aStyle)
{
MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(size));
MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(sizeAdjust));
MOZ_ASSERT(!mozilla::IsNaN(size));
MOZ_ASSERT(!mozilla::IsNaN(sizeAdjust));
if (weight > 900)
weight = 900;

View File

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

View File

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

View File

@ -19,6 +19,9 @@
using namespace js;
using mozilla::DoubleIsInt32;
using mozilla::IsNaN;
/*** OrderedHashTable ****************************************************************************/
@ -790,10 +793,10 @@ HashableValue::setValue(JSContext *cx, const Value &v)
} else if (v.isDouble()) {
double d = v.toDouble();
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.
value = Int32Value(i);
} else if (MOZ_DOUBLE_IS_NaN(d)) {
} else if (IsNaN(d)) {
// NaNs with different bits must hash and test identically.
value = DoubleValue(js_NaN);
} else {

View File

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

View File

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

View File

@ -21,6 +21,9 @@
using namespace js;
using namespace js::frontend;
using mozilla::IsNaN;
using mozilla::IsNegative;
static ParseNode *
ContainsVarOrConst(ParseNode *pn)
{
@ -147,13 +150,13 @@ FoldBinaryNumeric(JSContext *cx, JSOp op, ParseNode *pn1, ParseNode *pn2,
if (d2 == 0) {
#if defined(XP_WIN)
/* XXX MSVC miscompiles such that (NaN == 0) */
if (MOZ_DOUBLE_IS_NaN(d2))
if (IsNaN(d2))
d = js_NaN;
else
#endif
if (d == 0 || MOZ_DOUBLE_IS_NaN(d))
if (d == 0 || IsNaN(d))
d = js_NaN;
else if (MOZ_DOUBLE_IS_NEGATIVE(d) != MOZ_DOUBLE_IS_NEGATIVE(d2))
else if (IsNegative(d) != IsNegative(d2))
d = js_NegativeInfinity;
else
d = js_PositiveInfinity;
@ -202,7 +205,7 @@ Boolish(ParseNode *pn)
{
switch (pn->getOp()) {
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:
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. */
switch (pn1->getKind()) {
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;
break;
case PNK_STRING:
@ -678,7 +681,7 @@ FoldConstants<FullParseHandler>(JSContext *cx, ParseNode **pnp,
break;
case JSOP_NOT:
if (d == 0 || MOZ_DOUBLE_IS_NaN(d)) {
if (d == 0 || IsNaN(d)) {
pn->setKind(PNK_TRUE);
pn->setOp(JSOP_TRUE);
} else {

View File

@ -17,6 +17,8 @@
using namespace js;
using namespace js::frontend;
using mozilla::IsFinite;
/*
* Asserts to verify assumptions behind pn_ macros.
*/
@ -635,7 +637,7 @@ NullaryNode::dump()
case PNK_NUMBER: {
ToCStringBuf cbuf;
const char *cstr = NumberToCString(NULL, &cbuf, pn_dval);
if (!MOZ_DOUBLE_IS_FINITE(pn_dval))
if (!IsFinite(pn_dval))
fputc('#', stderr);
if (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");
// NaN != NaN
if (MOZ_DOUBLE_IS_NaN(global.constantValue())) {
if (!MOZ_DOUBLE_IS_NaN(v.toNumber()))
if (IsNaN(global.constantValue())) {
if (!IsNaN(v.toNumber()))
return LinkFail(cx, "global constant value needs to be NaN");
} else {
if (v.toNumber() != global.constantValue())

View File

@ -22,6 +22,10 @@ using namespace js;
using namespace js::ion;
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
// Static Single Assignment Form" by Gough and Klaren.
@ -579,14 +583,14 @@ MConstant::computeRange()
int exp = Range::MaxDoubleExponent;
// 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));
return;
}
// Infinity is used to set both lower and upper to the range boundaries.
if (MOZ_DOUBLE_IS_INFINITE(d)) {
if (MOZ_DOUBLE_IS_NEGATIVE(d))
if (IsInfinite(d)) {
if (IsNegative(d))
setRange(new Range(RANGE_INF_MIN, RANGE_INF_MIN, false, exp));
else
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.
exp = MOZ_DOUBLE_EXPONENT(d);
exp = ExponentComponent(d);
if (exp < 0) {
// This double only has a decimal part.
if (MOZ_DOUBLE_IS_NEGATIVE(d))
if (IsNegative(d))
setRange(new Range(-1, 0, true, 0));
else
setRange(new Range(0, 1, true, 0));
@ -614,7 +618,7 @@ MConstant::computeRange()
} else {
// This double has a precision loss. This also mean that it cannot
// encode any decimals.
if (MOZ_DOUBLE_IS_NEGATIVE(d))
if (IsNegative(d))
setRange(new Range(RANGE_INF_MIN, RANGE_INF_MIN, false, exp));
else
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
// operations. Double has 52 bits of mantissa, so 2^52+1 cannot be
// 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.
static const uint16_t MaxDoubleExponent = MOZ_DOUBLE_EXPONENT_BIAS;
static const uint16_t MaxDoubleExponent = mozilla::DoubleExponentBias;
private:
// Absolute ranges.

View File

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

View File

@ -502,7 +502,7 @@ JS_ValueToNumber(JSContext *cx, jsval valueArg, double *dp)
JS_PUBLIC_API(JSBool)
JS_DoubleIsInt32(double d, int32_t *ip)
{
return MOZ_DOUBLE_IS_INT32(d, ip);
return mozilla::DoubleIsInt32(d, ip);
}
JS_PUBLIC_API(int32_t)
@ -566,7 +566,7 @@ JS_ValueToInt32(JSContext *cx, jsval vArg, int32_t *ip)
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,
JSDVG_SEARCH_STACK, v, NullPtr());
return false;

View File

@ -1164,7 +1164,7 @@ JS_NumberValue(double d)
{
int32_t i;
d = JS_CANONICALIZE_NAN(d);
if (MOZ_DOUBLE_IS_INT32(d, &i))
if (mozilla::DoubleIsInt32(d, &i))
return INT_TO_JSVAL(i);
return DOUBLE_TO_JSVAL(d);
}
@ -1543,7 +1543,7 @@ ToBoolean(const Value &v)
return false;
if (v.isDouble()) {
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. */

View File

@ -47,6 +47,7 @@ using namespace js::types;
using mozilla::ArrayLength;
using mozilla::DebugOnly;
using mozilla::IsNaN;
using mozilla::PointerRangeSize;
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
* 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;
}

View File

@ -41,6 +41,8 @@
#include "vm/RegExpObject-inl.h"
using namespace js;
using mozilla::IsNaN;
using mozilla::LittleEndian;
using mozilla::NativeEndian;
@ -1058,7 +1060,7 @@ JSStructuredCloneReader::startRead(Value *vp)
double d;
if (!in.readDouble(&d) || !checkDouble(d))
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,
"date");
return false;

View File

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

View File

@ -29,6 +29,16 @@
using namespace js;
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
#define M_E 2.7182818284590452354
@ -68,8 +78,8 @@ MathCache::MathCache() {
memset(table, 0, sizeof(table));
/* See comments in lookup(). */
JS_ASSERT(MOZ_DOUBLE_IS_NEGATIVE_ZERO(-0.0));
JS_ASSERT(!MOZ_DOUBLE_IS_NEGATIVE_ZERO(+0.0));
JS_ASSERT(IsNegativeZero(-0.0));
JS_ASSERT(!IsNegativeZero(+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 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);
if (y < 0)
z *= 3;
@ -291,7 +301,7 @@ double
js::math_exp_impl(MathCache *cache, double x)
{
#ifdef _WIN32
if (!MOZ_DOUBLE_IS_NaN(x)) {
if (!IsNaN(x)) {
if (x == js_PositiveInfinity)
return js_PositiveInfinity;
if (x == js_NegativeInfinity)
@ -395,12 +405,12 @@ js_math_max(JSContext *cx, unsigned argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
double x;
double maxval = MOZ_DOUBLE_NEGATIVE_INFINITY();
double maxval = NegativeInfinity();
for (unsigned i = 0; i < args.length(); i++) {
if (!ToNumber(cx, args[i], &x))
return false;
// 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;
}
args.rval().setNumber(maxval);
@ -413,12 +423,12 @@ js_math_min(JSContext *cx, unsigned argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
double x;
double minval = MOZ_DOUBLE_POSITIVE_INFINITY();
double minval = PositiveInfinity();
for (unsigned i = 0; i < args.length(); i++) {
if (!ToNumber(cx, args[i], &x))
return false;
// 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;
}
args.rval().setNumber(minval);
@ -446,7 +456,7 @@ js::powi(double x, int y)
// given us a finite p. This happens very rarely.
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).
: result;
}
@ -478,7 +488,7 @@ js::ecmaPow(double x, double y)
* Because C99 and ECMA specify different behavior for pow(),
* 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;
/* pow(x, +-0) is always 1, even for x = NaN (MSVC gets this wrong). */
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)
* 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) {
vp->setNumber(sqrt(x));
return JS_TRUE;
@ -607,13 +617,13 @@ js_math_round(JSContext *cx, unsigned argc, Value *vp)
return false;
int32_t i;
if (MOZ_DOUBLE_IS_INT32(x, &i)) {
if (DoubleIsInt32(x, &i)) {
args.rval().setInt32(i);
return true;
}
/* Some numbers are so big that adding 0.5 would give the wrong number */
if (MOZ_DOUBLE_EXPONENT(x) >= 52) {
/* Some numbers are so big that adding 0.5 would give the wrong number. */
if (ExponentComponent(x) >= 52) {
args.rval().setNumber(x);
return true;
}

View File

@ -230,7 +230,7 @@ num_isNaN(JSContext *cx, unsigned argc, Value *vp)
double x;
if (!ToNumber(cx, vp[2], &x))
return false;
vp->setBoolean(MOZ_DOUBLE_IS_NaN(x));
vp->setBoolean(mozilla::IsNaN(x));
return JS_TRUE;
}
@ -244,7 +244,7 @@ num_isFinite(JSContext *cx, unsigned argc, Value *vp)
double x;
if (!ToNumber(cx, vp[2], &x))
return JS_FALSE;
vp->setBoolean(MOZ_DOUBLE_IS_FINITE(x));
vp->setBoolean(mozilla::IsFinite(x));
return JS_TRUE;
}
@ -911,7 +911,7 @@ Number_isNaN(JSContext *cx, unsigned argc, Value *vp)
args.rval().setBoolean(false);
return true;
}
args.rval().setBoolean(MOZ_DOUBLE_IS_NaN(args[0].toDouble()));
args.rval().setBoolean(mozilla::IsNaN(args[0].toDouble()));
return true;
}
@ -925,7 +925,7 @@ Number_isFinite(JSContext *cx, unsigned argc, Value *vp)
return true;
}
args.rval().setBoolean(args[0].isInt32() ||
MOZ_DOUBLE_IS_FINITE(args[0].toDouble()));
mozilla::IsFinite(args[0].toDouble()));
return true;
}
@ -940,7 +940,7 @@ Number_isInteger(JSContext *cx, unsigned argc, Value *vp)
}
Value val = args[0];
args.rval().setBoolean(val.isInt32() ||
(MOZ_DOUBLE_IS_FINITE(val.toDouble()) &&
(mozilla::IsFinite(val.toDouble()) &&
ToInteger(val.toDouble()) == val.toDouble()));
return true;
}
@ -1031,19 +1031,19 @@ js::InitRuntimeNumberState(JSRuntime *rt)
* Our NaN must be one particular canonical value, because we rely on NaN
* 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;
rt->NaNValue.setDouble(d);
d = MOZ_DOUBLE_POSITIVE_INFINITY();
d = mozilla::PositiveInfinity();
number_constants[NC_POSITIVE_INFINITY].dval = js_PositiveInfinity = d;
rt->positiveInfinityValue.setDouble(d);
d = MOZ_DOUBLE_NEGATIVE_INFINITY();
d = mozilla::NegativeInfinity();
number_constants[NC_NEGATIVE_INFINITY].dval = js_NegativeInfinity = 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,
// 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
{
int32_t _;
JS_ASSERT(!MOZ_DOUBLE_IS_INT32(d, &_));
JS_ASSERT(!mozilla::DoubleIsInt32(d, &_));
}
#endif
@ -1199,7 +1199,7 @@ char *
js::NumberToCString(JSContext *cx, ToCStringBuf *cbuf, double d, int base/* = 10*/)
{
int32_t i;
return MOZ_DOUBLE_IS_INT32(d, &i)
return mozilla::DoubleIsInt32(d, &i)
? IntToCString(cbuf, i, base)
: FracNumberToCString(cx, cbuf, d, base);
}
@ -1222,7 +1222,7 @@ js_NumberToStringWithBase(JSContext *cx, double d, int base)
JSCompartment *c = cx->compartment;
int32_t i;
if (MOZ_DOUBLE_IS_INT32(d, &i)) {
if (mozilla::DoubleIsInt32(d, &i)) {
if (base == 10 && StaticStrings::hasInt(i))
return cx->runtime->staticStrings.getInt(i);
if (unsigned(i) < unsigned(base)) {
@ -1476,7 +1476,7 @@ js::ToUint16Slow(JSContext *cx, const Value &v, uint16_t *out)
return false;
}
if (d == 0 || !MOZ_DOUBLE_IS_FINITE(d)) {
if (d == 0 || !mozilla::IsFinite(d)) {
*out = 0;
return true;
}

View File

@ -177,7 +177,7 @@ ValueFitsInInt32(const Value &v, int32_t *pi)
*pi = v.toInt32();
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;
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);
return true;
}

View File

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

View File

@ -63,6 +63,8 @@ using namespace js::types;
using namespace js::unicode;
using mozilla::CheckedInt;
using mozilla::IsNaN;
using mozilla::IsNegativeZero;
using mozilla::PodCopy;
using mozilla::PodEqual;
@ -1286,7 +1288,7 @@ str_lastIndexOf(JSContext *cx, unsigned argc, Value *vp)
double d;
if (!ToNumber(cx, args[1], &d))
return false;
if (!MOZ_DOUBLE_IS_NaN(d)) {
if (!IsNaN(d)) {
d = ToInteger(d);
if (d <= 0)
i = 0;
@ -3726,7 +3728,7 @@ js::ValueToSource(JSContext *cx, const Value &v)
return js_QuoteString(cx, v.toString(), '"');
if (v.isPrimitive()) {
/* 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. */
static const jschar js_negzero_ucNstr[] = {'-', '0'};

View File

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

View File

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

View File

@ -10,6 +10,8 @@
#include "jsutil.h"
using mozilla::UnspecifiedNaN;
static bool
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
// and all fields will be properly initialized.
localTZA_ = MOZ_DOUBLE_NaN();
localTZA_ = UnspecifiedNaN();
updateTimeZoneAdjustment();
}

View File

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

View File

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

View File

@ -244,9 +244,9 @@ def init_value(attribute):
return "0"
else:
if realtype.count("double") and attribute.defvalue == "Infinity":
return "MOZ_DOUBLE_POSITIVE_INFINITY()"
return "mozilla::PositiveInfinity()"
if realtype.count("double") and attribute.defvalue == "-Infinity":
return "MOZ_DOUBLE_NEGATIVE_INFINITY()"
return "mozilla::NegativeInfinity()"
if realtype.count("nsAString"):
return "NS_LITERAL_STRING(\"%s\")" % attribute.defvalue
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");
if (eCSSUnit_Percent <= aUnit) {
mValue.mFloat = aValue;
MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(mValue.mFloat));
MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
}
else {
mUnit = eCSSUnit_Null;
@ -105,7 +105,7 @@ nsCSSValue::nsCSSValue(const nsCSSValue& aCopy)
}
else if (eCSSUnit_Percent <= mUnit) {
mValue.mFloat = aCopy.mValue.mFloat;
MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(mValue.mFloat));
MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
}
else if (UnitHasStringValue()) {
mValue.mString = aCopy.mValue.mString;
@ -323,7 +323,7 @@ void nsCSSValue::SetPercentValue(float aValue)
Reset();
mUnit = eCSSUnit_Percent;
mValue.mFloat = aValue;
MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(mValue.mFloat));
MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
}
void nsCSSValue::SetFloatValue(float aValue, nsCSSUnit aUnit)
@ -333,7 +333,7 @@ void nsCSSValue::SetFloatValue(float aValue, nsCSSUnit aUnit)
if (eCSSUnit_Number <= aUnit) {
mUnit = aUnit;
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___
#include "mozilla/Attributes.h"
#include "mozilla/FloatingPoint.h"
#include "nsCOMPtr.h"
#include "nsCRTGlue.h"
@ -21,7 +22,6 @@
#include "nsStringBuffer.h"
#include "nsTArray.h"
#include "nsStyleConsts.h"
#include "mozilla/FloatingPoint.h"
class imgRequestProxy;
class nsIDocument;
@ -355,7 +355,7 @@ public:
float GetFloatValue() const
{
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;
}

View File

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

View File

@ -12,6 +12,8 @@
#include "mozilla/Attributes.h"
#include "mozilla/StandardInteger.h"
namespace mozilla {
/*
* 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
@ -25,10 +27,6 @@
* 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
* 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");
/*
* Constant expressions in C can't refer to consts, unfortunately, so #define
* 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
const unsigned DoubleExponentBias = 1023;
const unsigned DoubleExponentShift = 52;
#define MOZ_DOUBLE_EXPONENT_BIAS 1023
#define MOZ_DOUBLE_EXPONENT_SHIFT 52
namespace detail {
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");
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");
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");
MOZ_STATIC_ASSERT((MOZ_DOUBLE_SIGN_BIT | MOZ_DOUBLE_EXPONENT_BITS | MOZ_DOUBLE_SIGNIFICAND_BITS)
== ~(uint64_t)0,
MOZ_STATIC_ASSERT((DoubleSignBit | DoubleExponentBits | DoubleSignificandBits) ==
~uint64_t(0),
"all bits accounted for");
#ifdef __cplusplus
extern "C" {
#endif
/*
* This union is NOT a public data structure, and it is not to be used outside
* this file!
*/
union MozDoublePun {
union DoublePun
{
/*
* Every way to pun the bits of a double introduces an additional layer of
* complexity, across a multitude of platforms, architectures, and ABIs.
@ -80,165 +69,164 @@ union MozDoublePun {
double d;
};
} /* namespace detail */
/** Determines whether a double is NaN. */
static MOZ_ALWAYS_INLINE int
MOZ_DOUBLE_IS_NaN(double d)
static MOZ_ALWAYS_INLINE bool
IsNaN(double d)
{
union MozDoublePun pun;
union detail::DoublePun pun;
pun.d = d;
/*
* A double is NaN if all exponent bits are 1 and the significand contains at
* least one non-zero bit.
*/
return (pun.u & MOZ_DOUBLE_EXPONENT_BITS) == MOZ_DOUBLE_EXPONENT_BITS &&
(pun.u & MOZ_DOUBLE_SIGNIFICAND_BITS) != 0;
return (pun.u & detail::DoubleExponentBits) == detail::DoubleExponentBits &&
(pun.u & detail::DoubleSignificandBits) != 0;
}
/** Determines whether a double is +Infinity or -Infinity. */
static MOZ_ALWAYS_INLINE int
MOZ_DOUBLE_IS_INFINITE(double d)
static MOZ_ALWAYS_INLINE bool
IsInfinite(double d)
{
union MozDoublePun pun;
union detail::DoublePun pun;
pun.d = d;
/* 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. */
static MOZ_ALWAYS_INLINE int
MOZ_DOUBLE_IS_FINITE(double d)
static MOZ_ALWAYS_INLINE bool
IsFinite(double d)
{
union MozDoublePun pun;
union detail::DoublePun pun;
pun.d = d;
/*
* NaN and Infinities are the only non-finite doubles, and both have all
* 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
* on a double which is NaN.
*/
static MOZ_ALWAYS_INLINE int
MOZ_DOUBLE_IS_NEGATIVE(double d)
static MOZ_ALWAYS_INLINE bool
IsNegative(double d)
{
union MozDoublePun pun;
MOZ_ASSERT(!IsNaN(d), "NaN does not have a sign");
union detail::DoublePun pun;
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. */
return (pun.u & MOZ_DOUBLE_SIGN_BIT) != 0;
return (pun.u & detail::DoubleSignBit) != 0;
}
/** Determines whether a double represents -0. */
static MOZ_ALWAYS_INLINE int
MOZ_DOUBLE_IS_NEGATIVE_ZERO(double d)
static MOZ_ALWAYS_INLINE bool
IsNegativeZero(double d)
{
union MozDoublePun pun;
union detail::DoublePun pun;
pun.d = d;
/* 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. */
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;
/*
* The exponent component of a double is an unsigned number, biased from its
* actual value. Subtract the bias to retrieve the actual exponent.
*/
return (int_fast16_t)((pun.u & MOZ_DOUBLE_EXPONENT_BITS) >> MOZ_DOUBLE_EXPONENT_SHIFT) -
MOZ_DOUBLE_EXPONENT_BIAS;
return int_fast16_t((pun.u & detail::DoubleExponentBits) >> DoubleExponentShift) -
int_fast16_t(DoubleExponentBias);
}
/** Returns +Infinity. */
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
* significand.
*/
pun.u = MOZ_DOUBLE_EXPONENT_BITS;
pun.u = detail::DoubleExponentBits;
return pun.d;
}
/** Returns -Infinity. */
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
* significand.
*/
pun.u = MOZ_DOUBLE_SIGN_BIT | MOZ_DOUBLE_EXPONENT_BITS;
pun.u = detail::DoubleSignBit | detail::DoubleExponentBits;
return pun.d;
}
/** Constructs a NaN value with the specified sign bit and significand bits. */
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((significand & ~MOZ_DOUBLE_SIGNIFICAND_BITS) == 0);
MOZ_ASSERT(significand & MOZ_DOUBLE_SIGNIFICAND_BITS);
MOZ_ASSERT((significand & ~detail::DoubleSignificandBits) == 0);
MOZ_ASSERT(significand & detail::DoubleSignificandBits);
pun.u = (signbit ? MOZ_DOUBLE_SIGN_BIT : 0) |
MOZ_DOUBLE_EXPONENT_BITS |
union detail::DoublePun pun;
pun.u = (signbit ? detail::DoubleSignBit : 0) |
detail::DoubleExponentBits |
significand;
MOZ_ASSERT(MOZ_DOUBLE_IS_NaN(pun.d));
MOZ_ASSERT(IsNaN(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
* NaN value being returned.
*/
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. */
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
} /* namespace mozilla */
#endif /* mozilla_FloatingPoint_h_ */

View File

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