/src/mozilla-central/dom/xslt/xpath/txNumberExpr.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | txNumberExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult) |
14 | 0 | { |
15 | 0 | *aResult = nullptr; |
16 | 0 |
|
17 | 0 | RefPtr<txAExprResult> exprRes; |
18 | 0 | nsresult rv = mRightExpr->evaluate(aContext, getter_AddRefs(exprRes)); |
19 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
20 | 0 |
|
21 | 0 | double rightDbl = exprRes->numberValue(); |
22 | 0 |
|
23 | 0 | rv = mLeftExpr->evaluate(aContext, getter_AddRefs(exprRes)); |
24 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
25 | 0 |
|
26 | 0 | double leftDbl = exprRes->numberValue(); |
27 | 0 | double result = 0; |
28 | 0 |
|
29 | 0 | switch (mOp) { |
30 | 0 | case ADD: |
31 | 0 | result = leftDbl + rightDbl; |
32 | 0 | break; |
33 | 0 |
|
34 | 0 | case SUBTRACT: |
35 | 0 | result = leftDbl - rightDbl; |
36 | 0 | break; |
37 | 0 |
|
38 | 0 | 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 | 0 | else |
51 | 0 | result = mozilla::PositiveInfinity<double>(); |
52 | 0 | } |
53 | 0 | else |
54 | 0 | result = leftDbl / rightDbl; |
55 | 0 | break; |
56 | 0 |
|
57 | 0 | case MODULUS: |
58 | 0 | if (rightDbl == 0) { |
59 | 0 | result = mozilla::UnspecifiedNaN<double>(); |
60 | 0 | } |
61 | 0 | 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 | | result = fmod(leftDbl, rightDbl); |
69 | 0 | } |
70 | 0 | break; |
71 | 0 |
|
72 | 0 | case MULTIPLY: |
73 | 0 | result = leftDbl * rightDbl; |
74 | 0 | break; |
75 | 0 | } |
76 | 0 | |
77 | 0 | return aContext->recycler()->getNumberResult(result, aResult); |
78 | 0 | } //-- evaluate |
79 | | |
80 | | TX_IMPL_EXPR_STUBS_2(txNumberExpr, NUMBER_RESULT, mLeftExpr, mRightExpr) |
81 | | |
82 | | bool |
83 | | txNumberExpr::isSensitiveTo(ContextSensitivity aContext) |
84 | 0 | { |
85 | 0 | return mLeftExpr->isSensitiveTo(aContext) || |
86 | 0 | mRightExpr->isSensitiveTo(aContext); |
87 | 0 | } |
88 | | |
89 | | #ifdef TX_TO_STRING |
90 | | void |
91 | | txNumberExpr::toString(nsAString& str) |
92 | | { |
93 | | mLeftExpr->toString(str); |
94 | | |
95 | | switch (mOp) { |
96 | | case ADD: |
97 | | str.AppendLiteral(" + "); |
98 | | break; |
99 | | case SUBTRACT: |
100 | | str.AppendLiteral(" - "); |
101 | | break; |
102 | | case DIVIDE: |
103 | | str.AppendLiteral(" div "); |
104 | | break; |
105 | | case MODULUS: |
106 | | str.AppendLiteral(" mod "); |
107 | | break; |
108 | | case MULTIPLY: |
109 | | str.AppendLiteral(" * "); |
110 | | break; |
111 | | } |
112 | | |
113 | | mRightExpr->toString(str); |
114 | | |
115 | | } |
116 | | #endif |