txNumberExpr.cpp (2855B)
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/. */ 5 6 #include <math.h> 7 8 #include "mozilla/FloatingPoint.h" 9 #include "txExpr.h" 10 #include "txIXPathContext.h" 11 12 nsresult txNumberExpr::evaluate(txIEvalContext* aContext, 13 txAExprResult** aResult) { 14 *aResult = nullptr; 15 16 RefPtr<txAExprResult> exprRes; 17 nsresult rv = mRightExpr->evaluate(aContext, getter_AddRefs(exprRes)); 18 NS_ENSURE_SUCCESS(rv, rv); 19 20 double rightDbl = exprRes->numberValue(); 21 22 rv = mLeftExpr->evaluate(aContext, getter_AddRefs(exprRes)); 23 NS_ENSURE_SUCCESS(rv, rv); 24 25 double leftDbl = exprRes->numberValue(); 26 double result = 0; 27 28 switch (mOp) { 29 case ADD: 30 result = leftDbl + rightDbl; 31 break; 32 33 case SUBTRACT: 34 result = leftDbl - rightDbl; 35 break; 36 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; 54 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); 66 } 67 break; 68 69 case MULTIPLY: 70 result = leftDbl * rightDbl; 71 break; 72 } 73 74 return aContext->recycler()->getNumberResult(result, aResult); 75 } //-- evaluate 76 77 TX_IMPL_EXPR_STUBS_2(txNumberExpr, NUMBER_RESULT, mLeftExpr, mRightExpr) 78 79 bool txNumberExpr::isSensitiveTo(ContextSensitivity aContext) { 80 return mLeftExpr->isSensitiveTo(aContext) || 81 mRightExpr->isSensitiveTo(aContext); 82 } 83 84 #ifdef TX_TO_STRING 85 void txNumberExpr::toString(nsAString& str) { 86 mLeftExpr->toString(str); 87 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; 104 } 105 106 mRightExpr->toString(str); 107 } 108 #endif