1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "mozilla/FloatingPoint.h"
10 #include "txIXPathContext.h"
12 nsresult
txNumberExpr::evaluate(txIEvalContext
* aContext
,
13 txAExprResult
** aResult
) {
16 RefPtr
<txAExprResult
> exprRes
;
17 nsresult rv
= mRightExpr
->evaluate(aContext
, getter_AddRefs(exprRes
));
18 NS_ENSURE_SUCCESS(rv
, rv
);
20 double rightDbl
= exprRes
->numberValue();
22 rv
= mLeftExpr
->evaluate(aContext
, getter_AddRefs(exprRes
));
23 NS_ENSURE_SUCCESS(rv
, rv
);
25 double leftDbl
= exprRes
->numberValue();
30 result
= leftDbl
+ rightDbl
;
34 result
= leftDbl
- rightDbl
;
40 /* XXX MSVC miscompiles such that (NaN == 0) */
41 if (std::isnan(rightDbl
))
42 result
= mozilla::UnspecifiedNaN
<double>();
45 if (leftDbl
== 0 || std::isnan(leftDbl
))
46 result
= mozilla::UnspecifiedNaN
<double>();
47 else if (mozilla::IsNegative(leftDbl
) != mozilla::IsNegative(rightDbl
))
48 result
= mozilla::NegativeInfinity
<double>();
50 result
= mozilla::PositiveInfinity
<double>();
52 result
= leftDbl
/ rightDbl
;
57 result
= mozilla::UnspecifiedNaN
<double>();
60 /* Workaround MS fmod bug where 42 % (1/0) => NaN, not 42. */
61 if (!std::isinf(leftDbl
) && std::isinf(rightDbl
))
65 result
= fmod(leftDbl
, rightDbl
);
70 result
= leftDbl
* rightDbl
;
74 return aContext
->recycler()->getNumberResult(result
, aResult
);
77 TX_IMPL_EXPR_STUBS_2(txNumberExpr
, NUMBER_RESULT
, mLeftExpr
, mRightExpr
)
79 bool txNumberExpr::isSensitiveTo(ContextSensitivity aContext
) {
80 return mLeftExpr
->isSensitiveTo(aContext
) ||
81 mRightExpr
->isSensitiveTo(aContext
);
85 void txNumberExpr::toString(nsAString
& str
) {
86 mLeftExpr
->toString(str
);
90 str
.AppendLiteral(" + ");
93 str
.AppendLiteral(" - ");
96 str
.AppendLiteral(" div ");
99 str
.AppendLiteral(" mod ");
102 str
.AppendLiteral(" * ");
106 mRightExpr
->toString(str
);