Bug 1874684 - Part 4: Prefer const references instead of copying Instant values....
[gecko.git] / dom / xslt / xpath / txNumberExpr.cpp
blobc3424a91f192ce7aa3b280a15707e901c5e2224a
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"
8 #include "txExpr.h"
9 #include <math.h>
10 #include "txIXPathContext.h"
12 nsresult txNumberExpr::evaluate(txIEvalContext* aContext,
13 txAExprResult** aResult) {
14 *aResult = nullptr;
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();
26 double result = 0;
28 switch (mOp) {
29 case ADD:
30 result = leftDbl + rightDbl;
31 break;
33 case SUBTRACT:
34 result = leftDbl - rightDbl;
35 break;
37 case DIVIDE:
38 if (rightDbl == 0) {
39 #if defined(XP_WIN)
40 /* XXX MSVC miscompiles such that (NaN == 0) */
41 if (std::isnan(rightDbl))
42 result = mozilla::UnspecifiedNaN<double>();
43 else
44 #endif
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>();
49 else
50 result = mozilla::PositiveInfinity<double>();
51 } else
52 result = leftDbl / rightDbl;
53 break;
55 case MODULUS:
56 if (rightDbl == 0) {
57 result = mozilla::UnspecifiedNaN<double>();
58 } else {
59 #if defined(XP_WIN)
60 /* Workaround MS fmod bug where 42 % (1/0) => NaN, not 42. */
61 if (!std::isinf(leftDbl) && std::isinf(rightDbl))
62 result = leftDbl;
63 else
64 #endif
65 result = fmod(leftDbl, rightDbl);
67 break;
69 case MULTIPLY:
70 result = leftDbl * rightDbl;
71 break;
74 return aContext->recycler()->getNumberResult(result, aResult);
75 } //-- evaluate
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);
84 #ifdef TX_TO_STRING
85 void txNumberExpr::toString(nsAString& str) {
86 mLeftExpr->toString(str);
88 switch (mOp) {
89 case ADD:
90 str.AppendLiteral(" + ");
91 break;
92 case SUBTRACT:
93 str.AppendLiteral(" - ");
94 break;
95 case DIVIDE:
96 str.AppendLiteral(" div ");
97 break;
98 case MODULUS:
99 str.AppendLiteral(" mod ");
100 break;
101 case MULTIPLY:
102 str.AppendLiteral(" * ");
103 break;
106 mRightExpr->toString(str);
108 #endif