Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/. */
5 :
6 : #include "mozilla/FloatingPoint.h"
7 :
8 : #include "txExpr.h"
9 : #include <math.h>
10 : #include "txIXPathContext.h"
11 :
12 : nsresult
13 0 : txNumberExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
14 : {
15 0 : *aResult = nullptr;
16 :
17 0 : RefPtr<txAExprResult> exprRes;
18 0 : nsresult rv = mRightExpr->evaluate(aContext, getter_AddRefs(exprRes));
19 0 : NS_ENSURE_SUCCESS(rv, rv);
20 :
21 0 : double rightDbl = exprRes->numberValue();
22 :
23 0 : rv = mLeftExpr->evaluate(aContext, getter_AddRefs(exprRes));
24 0 : NS_ENSURE_SUCCESS(rv, rv);
25 :
26 0 : double leftDbl = exprRes->numberValue();
27 0 : double result = 0;
28 :
29 0 : switch (mOp) {
30 : case ADD:
31 0 : result = leftDbl + rightDbl;
32 0 : break;
33 :
34 : case SUBTRACT:
35 0 : result = leftDbl - rightDbl;
36 0 : break;
37 :
38 : case DIVIDE:
39 0 : if (rightDbl == 0) {
40 : #if defined(XP_WIN)
41 : /* XXX MSVC miscompiles such that (NaN == 0) */
42 : if (mozilla::IsNaN(rightDbl))
43 : result = mozilla::UnspecifiedNaN<double>();
44 : else
45 : #endif
46 0 : if (leftDbl == 0 || mozilla::IsNaN(leftDbl))
47 0 : result = mozilla::UnspecifiedNaN<double>();
48 0 : else if (mozilla::IsNegative(leftDbl) != mozilla::IsNegative(rightDbl))
49 0 : result = mozilla::NegativeInfinity<double>();
50 : else
51 0 : result = mozilla::PositiveInfinity<double>();
52 : }
53 : else
54 0 : result = leftDbl / rightDbl;
55 0 : break;
56 :
57 : case MODULUS:
58 0 : if (rightDbl == 0) {
59 0 : result = mozilla::UnspecifiedNaN<double>();
60 : }
61 : else {
62 : #if defined(XP_WIN)
63 : /* Workaround MS fmod bug where 42 % (1/0) => NaN, not 42. */
64 : if (!mozilla::IsInfinite(leftDbl) && mozilla::IsInfinite(rightDbl))
65 : result = leftDbl;
66 : else
67 : #endif
68 0 : result = fmod(leftDbl, rightDbl);
69 : }
70 0 : break;
71 :
72 : case MULTIPLY:
73 0 : result = leftDbl * rightDbl;
74 0 : break;
75 : }
76 :
77 0 : return aContext->recycler()->getNumberResult(result, aResult);
78 : } //-- evaluate
79 :
80 0 : TX_IMPL_EXPR_STUBS_2(txNumberExpr, NUMBER_RESULT, mLeftExpr, mRightExpr)
81 :
82 : bool
83 0 : txNumberExpr::isSensitiveTo(ContextSensitivity aContext)
84 : {
85 0 : return mLeftExpr->isSensitiveTo(aContext) ||
86 0 : mRightExpr->isSensitiveTo(aContext);
87 : }
88 :
89 : #ifdef TX_TO_STRING
90 : void
91 0 : txNumberExpr::toString(nsAString& str)
92 : {
93 0 : mLeftExpr->toString(str);
94 :
95 0 : switch (mOp) {
96 : case ADD:
97 0 : str.AppendLiteral(" + ");
98 0 : break;
99 : case SUBTRACT:
100 0 : str.AppendLiteral(" - ");
101 0 : break;
102 : case DIVIDE:
103 0 : str.AppendLiteral(" div ");
104 0 : break;
105 : case MODULUS:
106 0 : str.AppendLiteral(" mod ");
107 0 : break;
108 : case MULTIPLY:
109 0 : str.AppendLiteral(" * ");
110 0 : break;
111 : }
112 :
113 0 : mRightExpr->toString(str);
114 :
115 0 : }
116 : #endif
|