Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | #include "mozilla/FloatingPoint.h" |
michael@0 | 7 | |
michael@0 | 8 | #include "txExpr.h" |
michael@0 | 9 | #include <math.h> |
michael@0 | 10 | #include "txIXPathContext.h" |
michael@0 | 11 | |
michael@0 | 12 | nsresult |
michael@0 | 13 | txNumberExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult) |
michael@0 | 14 | { |
michael@0 | 15 | *aResult = nullptr; |
michael@0 | 16 | |
michael@0 | 17 | nsRefPtr<txAExprResult> exprRes; |
michael@0 | 18 | nsresult rv = mRightExpr->evaluate(aContext, getter_AddRefs(exprRes)); |
michael@0 | 19 | NS_ENSURE_SUCCESS(rv, rv); |
michael@0 | 20 | |
michael@0 | 21 | double rightDbl = exprRes->numberValue(); |
michael@0 | 22 | |
michael@0 | 23 | rv = mLeftExpr->evaluate(aContext, getter_AddRefs(exprRes)); |
michael@0 | 24 | NS_ENSURE_SUCCESS(rv, rv); |
michael@0 | 25 | |
michael@0 | 26 | double leftDbl = exprRes->numberValue(); |
michael@0 | 27 | double result = 0; |
michael@0 | 28 | |
michael@0 | 29 | switch (mOp) { |
michael@0 | 30 | case ADD: |
michael@0 | 31 | result = leftDbl + rightDbl; |
michael@0 | 32 | break; |
michael@0 | 33 | |
michael@0 | 34 | case SUBTRACT: |
michael@0 | 35 | result = leftDbl - rightDbl; |
michael@0 | 36 | break; |
michael@0 | 37 | |
michael@0 | 38 | case DIVIDE: |
michael@0 | 39 | if (rightDbl == 0) { |
michael@0 | 40 | #if defined(XP_WIN) |
michael@0 | 41 | /* XXX MSVC miscompiles such that (NaN == 0) */ |
michael@0 | 42 | if (mozilla::IsNaN(rightDbl)) |
michael@0 | 43 | result = mozilla::UnspecifiedNaN<double>(); |
michael@0 | 44 | else |
michael@0 | 45 | #endif |
michael@0 | 46 | if (leftDbl == 0 || mozilla::IsNaN(leftDbl)) |
michael@0 | 47 | result = mozilla::UnspecifiedNaN<double>(); |
michael@0 | 48 | else if (mozilla::IsNegative(leftDbl) != mozilla::IsNegative(rightDbl)) |
michael@0 | 49 | result = mozilla::NegativeInfinity<double>(); |
michael@0 | 50 | else |
michael@0 | 51 | result = mozilla::PositiveInfinity<double>(); |
michael@0 | 52 | } |
michael@0 | 53 | else |
michael@0 | 54 | result = leftDbl / rightDbl; |
michael@0 | 55 | break; |
michael@0 | 56 | |
michael@0 | 57 | case MODULUS: |
michael@0 | 58 | if (rightDbl == 0) { |
michael@0 | 59 | result = mozilla::UnspecifiedNaN<double>(); |
michael@0 | 60 | } |
michael@0 | 61 | else { |
michael@0 | 62 | #if defined(XP_WIN) |
michael@0 | 63 | /* Workaround MS fmod bug where 42 % (1/0) => NaN, not 42. */ |
michael@0 | 64 | if (!mozilla::IsInfinite(leftDbl) && mozilla::IsInfinite(rightDbl)) |
michael@0 | 65 | result = leftDbl; |
michael@0 | 66 | else |
michael@0 | 67 | #endif |
michael@0 | 68 | result = fmod(leftDbl, rightDbl); |
michael@0 | 69 | } |
michael@0 | 70 | break; |
michael@0 | 71 | |
michael@0 | 72 | case MULTIPLY: |
michael@0 | 73 | result = leftDbl * rightDbl; |
michael@0 | 74 | break; |
michael@0 | 75 | } |
michael@0 | 76 | |
michael@0 | 77 | return aContext->recycler()->getNumberResult(result, aResult); |
michael@0 | 78 | } //-- evaluate |
michael@0 | 79 | |
michael@0 | 80 | TX_IMPL_EXPR_STUBS_2(txNumberExpr, NUMBER_RESULT, mLeftExpr, mRightExpr) |
michael@0 | 81 | |
michael@0 | 82 | bool |
michael@0 | 83 | txNumberExpr::isSensitiveTo(ContextSensitivity aContext) |
michael@0 | 84 | { |
michael@0 | 85 | return mLeftExpr->isSensitiveTo(aContext) || |
michael@0 | 86 | mRightExpr->isSensitiveTo(aContext); |
michael@0 | 87 | } |
michael@0 | 88 | |
michael@0 | 89 | #ifdef TX_TO_STRING |
michael@0 | 90 | void |
michael@0 | 91 | txNumberExpr::toString(nsAString& str) |
michael@0 | 92 | { |
michael@0 | 93 | mLeftExpr->toString(str); |
michael@0 | 94 | |
michael@0 | 95 | switch (mOp) { |
michael@0 | 96 | case ADD: |
michael@0 | 97 | str.AppendLiteral(" + "); |
michael@0 | 98 | break; |
michael@0 | 99 | case SUBTRACT: |
michael@0 | 100 | str.AppendLiteral(" - "); |
michael@0 | 101 | break; |
michael@0 | 102 | case DIVIDE: |
michael@0 | 103 | str.AppendLiteral(" div "); |
michael@0 | 104 | break; |
michael@0 | 105 | case MODULUS: |
michael@0 | 106 | str.AppendLiteral(" mod "); |
michael@0 | 107 | break; |
michael@0 | 108 | case MULTIPLY: |
michael@0 | 109 | str.AppendLiteral(" * "); |
michael@0 | 110 | break; |
michael@0 | 111 | } |
michael@0 | 112 | |
michael@0 | 113 | mRightExpr->toString(str); |
michael@0 | 114 | |
michael@0 | 115 | } |
michael@0 | 116 | #endif |