From fa30cbd2f00e005b0c3e7e0f89c6a95dc2bbc794 Mon Sep 17 00:00:00 2001 From: Trevor Saunders Date: Thu, 19 May 2011 12:35:46 -0700 Subject: [PATCH] bug 658363 - move defines for double constants out of xslt r=sicking From 57a4aaadf8fef828764c35dad01ce6da54fbb638 Mon Sep 17 00:00:00 2001 xslt --- content/base/public/nsContentUtils.h | 93 +++++++++++++++++++ content/xslt/public/Makefile.in | 1 - content/xslt/public/txDouble.h | 133 --------------------------- content/xslt/src/base/txCore.h | 8 +- content/xslt/src/base/txDouble.cpp | 18 ++-- content/xslt/src/xpath/txRelationalExpr.cpp | 12 +- 6 files changed, 112 insertions(+), 153 deletions(-) delete mode 100644 content/xslt/public/txDouble.h --- content/base/public/nsContentUtils.h | 93 ++++++++++++++ content/xslt/public/Makefile.in | 1 - content/xslt/public/txDouble.h | 133 -------------------- content/xslt/src/base/txCore.h | 8 +- content/xslt/src/base/txDouble.cpp | 18 +-- content/xslt/src/xpath/txRelationalExpr.cpp | 12 +- 6 files changed, 112 insertions(+), 153 deletions(-) delete mode 100644 content/xslt/public/txDouble.h diff --git a/content/base/public/nsContentUtils.h b/content/base/public/nsContentUtils.h index 4bd8181e5a5..73ee4bf0e66 100644 --- a/content/base/public/nsContentUtils.h +++ b/content/base/public/nsContentUtils.h @@ -51,6 +51,17 @@ #include #endif +//A trick to handle IEEE floating point exceptions on FreeBSD - E.D. +#ifdef __FreeBSD__ +#include +#ifdef __alpha__ +static fp_except_t allmask = FP_X_INV|FP_X_OFL|FP_X_UFL|FP_X_DZ|FP_X_IMP; +#else +static fp_except_t allmask = FP_X_INV|FP_X_OFL|FP_X_UFL|FP_X_DZ|FP_X_IMP|FP_X_DNML; +#endif +static fp_except_t oldmask = fpsetmask(~allmask); +#endif + #include "nsAString.h" #include "nsIStatefulFrame.h" #include "nsINodeInfo.h" @@ -1929,6 +1940,88 @@ public: } \ } else +/** + * Macros to workaround math-bugs bugs in various platforms + */ + +/** + * Stefan Hanske reports: + * ARM is a little endian architecture but 64 bit double words are stored + * differently: the 32 bit words are in little endian byte order, the two words + * are stored in big endian`s way. + */ + +#if defined(__arm) || defined(__arm32__) || defined(__arm26__) || defined(__arm__) +#if !defined(__VFP_FP__) +#define FPU_IS_ARM_FPA +#endif +#endif + +typedef union dpun { + struct { +#if defined(IS_LITTLE_ENDIAN) && !defined(FPU_IS_ARM_FPA) + PRUint32 lo, hi; +#else + PRUint32 hi, lo; +#endif + } s; + PRFloat64 d; +public: + operator double() const { + return d; + } +} dpun; + +/** + * Utility class for doubles + */ +#if (__GNUC__ == 2 && __GNUC_MINOR__ > 95) || __GNUC__ > 2 +/** + * This version of the macros is safe for the alias optimizations + * that gcc does, but uses gcc-specific extensions. + */ +#define DOUBLE_HI32(x) (__extension__ ({ dpun u; u.d = (x); u.s.hi; })) +#define DOUBLE_LO32(x) (__extension__ ({ dpun u; u.d = (x); u.s.lo; })) + +#else // __GNUC__ + +/* We don't know of any non-gcc compilers that perform alias optimization, + * so this code should work. + */ + +#if defined(IS_LITTLE_ENDIAN) && !defined(FPU_IS_ARM_FPA) +#define DOUBLE_HI32(x) (((PRUint32 *)&(x))[1]) +#define DOUBLE_LO32(x) (((PRUint32 *)&(x))[0]) +#else +#define DOUBLE_HI32(x) (((PRUint32 *)&(x))[0]) +#define DOUBLE_LO32(x) (((PRUint32 *)&(x))[1]) +#endif + +#endif // __GNUC__ + +#define DOUBLE_HI32_SIGNBIT 0x80000000 +#define DOUBLE_HI32_EXPMASK 0x7ff00000 +#define DOUBLE_HI32_MANTMASK 0x000fffff + +#define DOUBLE_IS_NaN(x) \ +((DOUBLE_HI32(x) & DOUBLE_HI32_EXPMASK) == DOUBLE_HI32_EXPMASK && \ + (DOUBLE_LO32(x) || (DOUBLE_HI32(x) & DOUBLE_HI32_MANTMASK))) + +#ifdef IS_BIG_ENDIAN +#define DOUBLE_NaN {{DOUBLE_HI32_EXPMASK | DOUBLE_HI32_MANTMASK, \ + 0xffffffff}} +#else +#define DOUBLE_NaN {{0xffffffff, \ + DOUBLE_HI32_EXPMASK | DOUBLE_HI32_MANTMASK}} +#endif + +#if defined(XP_WIN) +#define DOUBLE_COMPARE(LVAL, OP, RVAL) \ + (!DOUBLE_IS_NaN(LVAL) && !DOUBLE_IS_NaN(RVAL) && (LVAL) OP (RVAL)) +#else +#define DOUBLE_COMPARE(LVAL, OP, RVAL) ((LVAL) OP (RVAL)) +#endif + /* * Check whether a floating point number is finite (not +/-infinity and not a * NaN value). diff --git a/content/xslt/public/Makefile.in b/content/xslt/public/Makefile.in index 3df73af0da4..3bfa32ccb8a 100644 --- a/content/xslt/public/Makefile.in +++ b/content/xslt/public/Makefile.in @@ -47,7 +47,6 @@ XPIDL_MODULE = content_xslt EXPORTS = \ nsIDocumentTransformer.h \ - txDouble.h \ $(NULL) XPIDLSRCS = \ diff --git a/content/xslt/public/txDouble.h b/content/xslt/public/txDouble.h deleted file mode 100644 index ec8e964c1b5..00000000000 --- a/content/xslt/public/txDouble.h +++ /dev/null @@ -1,133 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Peter Van der Beken. - * Portions created by the Initial Developer are Copyright (C) 2005 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Peter Van der Beken - * - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef __txdouble_h__ -#define __txdouble_h__ - -//A trick to handle IEEE floating point exceptions on FreeBSD - E.D. -#ifdef __FreeBSD__ -#include -#ifdef __alpha__ -static fp_except_t allmask = FP_X_INV|FP_X_OFL|FP_X_UFL|FP_X_DZ|FP_X_IMP; -#else -static fp_except_t allmask = FP_X_INV|FP_X_OFL|FP_X_UFL|FP_X_DZ|FP_X_IMP|FP_X_DNML; -#endif -static fp_except_t oldmask = fpsetmask(~allmask); -#endif - -/** - * Macros to workaround math-bugs bugs in various platforms - */ - -/** - * Stefan Hanske reports: - * ARM is a little endian architecture but 64 bit double words are stored - * differently: the 32 bit words are in little endian byte order, the two words - * are stored in big endian`s way. - */ - -#if defined(__arm) || defined(__arm32__) || defined(__arm26__) || defined(__arm__) -#if !defined(__VFP_FP__) -#define FPU_IS_ARM_FPA -#endif -#endif - -typedef union txdpun { - struct { -#if defined(IS_LITTLE_ENDIAN) && !defined(FPU_IS_ARM_FPA) - PRUint32 lo, hi; -#else - PRUint32 hi, lo; -#endif - } s; - PRFloat64 d; -public: - operator double() const { - return d; - } -} txdpun; - -#if (__GNUC__ == 2 && __GNUC_MINOR__ > 95) || __GNUC__ > 2 -/** - * This version of the macros is safe for the alias optimizations - * that gcc does, but uses gcc-specific extensions. - */ -#define TX_DOUBLE_HI32(x) (__extension__ ({ txdpun u; u.d = (x); u.s.hi; })) -#define TX_DOUBLE_LO32(x) (__extension__ ({ txdpun u; u.d = (x); u.s.lo; })) - -#else // __GNUC__ - -/* We don't know of any non-gcc compilers that perform alias optimization, - * so this code should work. - */ - -#if defined(IS_LITTLE_ENDIAN) && !defined(FPU_IS_ARM_FPA) -#define TX_DOUBLE_HI32(x) (((PRUint32 *)&(x))[1]) -#define TX_DOUBLE_LO32(x) (((PRUint32 *)&(x))[0]) -#else -#define TX_DOUBLE_HI32(x) (((PRUint32 *)&(x))[0]) -#define TX_DOUBLE_LO32(x) (((PRUint32 *)&(x))[1]) -#endif - -#endif // __GNUC__ - -#define TX_DOUBLE_HI32_SIGNBIT 0x80000000 -#define TX_DOUBLE_HI32_EXPMASK 0x7ff00000 -#define TX_DOUBLE_HI32_MANTMASK 0x000fffff - -#define TX_DOUBLE_IS_NaN(x) \ -((TX_DOUBLE_HI32(x) & TX_DOUBLE_HI32_EXPMASK) == TX_DOUBLE_HI32_EXPMASK && \ - (TX_DOUBLE_LO32(x) || (TX_DOUBLE_HI32(x) & TX_DOUBLE_HI32_MANTMASK))) - -#ifdef IS_BIG_ENDIAN -#define TX_DOUBLE_NaN {{TX_DOUBLE_HI32_EXPMASK | TX_DOUBLE_HI32_MANTMASK, \ - 0xffffffff}} -#else -#define TX_DOUBLE_NaN {{0xffffffff, \ - TX_DOUBLE_HI32_EXPMASK | TX_DOUBLE_HI32_MANTMASK}} -#endif - -#if defined(XP_WIN) -#define TX_DOUBLE_COMPARE(LVAL, OP, RVAL) \ - (!TX_DOUBLE_IS_NaN(LVAL) && !TX_DOUBLE_IS_NaN(RVAL) && (LVAL) OP (RVAL)) -#else -#define TX_DOUBLE_COMPARE(LVAL, OP, RVAL) ((LVAL) OP (RVAL)) -#endif - -#endif /* __txdouble_h__ */ diff --git a/content/xslt/src/base/txCore.h b/content/xslt/src/base/txCore.h index 1b973c4cc62..a716b661a3c 100644 --- a/content/xslt/src/base/txCore.h +++ b/content/xslt/src/base/txCore.h @@ -39,11 +39,11 @@ #ifndef __txCore_h__ #define __txCore_h__ +#include "nsContentUtils.h" #include "nscore.h" #include "nsDebug.h" #include "nsTraceRefcnt.h" #include "prtypes.h" -#include "txDouble.h" class nsAString; @@ -73,9 +73,9 @@ public: /** * Useful constants */ - static const txdpun NaN; - static const txdpun POSITIVE_INFINITY; - static const txdpun NEGATIVE_INFINITY; + static const dpun NaN; + static const dpun POSITIVE_INFINITY; + static const dpun NEGATIVE_INFINITY; /** * Determines whether the given double represents positive or negative diff --git a/content/xslt/src/base/txDouble.cpp b/content/xslt/src/base/txDouble.cpp index 4349bc50d19..e5f4c77f7c8 100644 --- a/content/xslt/src/base/txDouble.cpp +++ b/content/xslt/src/base/txDouble.cpp @@ -50,13 +50,13 @@ */ //-- Initialize Double related constants -const txdpun Double::NaN = TX_DOUBLE_NaN; +const dpun Double::NaN = DOUBLE_NaN; #ifdef IS_BIG_ENDIAN -const txdpun Double::POSITIVE_INFINITY = {{TX_DOUBLE_HI32_EXPMASK, 0}}; -const txdpun Double::NEGATIVE_INFINITY = {{TX_DOUBLE_HI32_EXPMASK | TX_DOUBLE_HI32_SIGNBIT, 0}}; +const dpun Double::POSITIVE_INFINITY = {{DOUBLE_HI32_EXPMASK, 0}}; +const txdpun Double::NEGATIVE_INFINITY = {{DOUBLE_HI32_EXPMASK | DOUBLE_HI32_SIGNBIT, 0}}; #else -const txdpun Double::POSITIVE_INFINITY = {{0, TX_DOUBLE_HI32_EXPMASK}}; -const txdpun Double::NEGATIVE_INFINITY = {{0, TX_DOUBLE_HI32_EXPMASK | TX_DOUBLE_HI32_SIGNBIT}}; +const dpun Double::POSITIVE_INFINITY = {{0, DOUBLE_HI32_EXPMASK}}; +const dpun Double::NEGATIVE_INFINITY = {{0, DOUBLE_HI32_EXPMASK | DOUBLE_HI32_SIGNBIT}}; #endif /* @@ -65,8 +65,8 @@ const txdpun Double::NEGATIVE_INFINITY = {{0, TX_DOUBLE_HI32_EXPMASK | TX_DOUBLE */ MBool Double::isInfinite(double aDbl) { - return ((TX_DOUBLE_HI32(aDbl) & ~TX_DOUBLE_HI32_SIGNBIT) == TX_DOUBLE_HI32_EXPMASK && - !TX_DOUBLE_LO32(aDbl)); + return ((DOUBLE_HI32(aDbl) & ~DOUBLE_HI32_SIGNBIT) == DOUBLE_HI32_EXPMASK && + !DOUBLE_LO32(aDbl)); } /* @@ -74,7 +74,7 @@ MBool Double::isInfinite(double aDbl) */ MBool Double::isNaN(double aDbl) { - return TX_DOUBLE_IS_NaN(aDbl); + return DOUBLE_IS_NaN(aDbl); } /* @@ -82,7 +82,7 @@ MBool Double::isNaN(double aDbl) */ MBool Double::isNeg(double aDbl) { - return (TX_DOUBLE_HI32(aDbl) & TX_DOUBLE_HI32_SIGNBIT) != 0; + return (DOUBLE_HI32(aDbl) & DOUBLE_HI32_SIGNBIT) != 0; } /* diff --git a/content/xslt/src/xpath/txRelationalExpr.cpp b/content/xslt/src/xpath/txRelationalExpr.cpp index a97f4b29718..caae4fc3577 100644 --- a/content/xslt/src/xpath/txRelationalExpr.cpp +++ b/content/xslt/src/xpath/txRelationalExpr.cpp @@ -36,8 +36,8 @@ * * ***** END LICENSE BLOCK ***** */ +#include "nsContentUtils.h" #include "txExpr.h" -#include "txDouble.h" #include "txNodeSet.h" #include "txIXPathContext.h" #include "txXPathTreeWalker.h" @@ -119,7 +119,7 @@ RelationalExpr::compareResults(txIEvalContext* aContext, txAExprResult* aLeft, rtype == txAExprResult::NUMBER) { double lval = aLeft->numberValue(); double rval = aRight->numberValue(); - result = TX_DOUBLE_COMPARE(lval, ==, rval); + result = DOUBLE_COMPARE(lval, ==, rval); } // Otherwise compare as strings. Try to use the stringobject in @@ -154,19 +154,19 @@ RelationalExpr::compareResults(txIEvalContext* aContext, txAExprResult* aLeft, switch (mOp) { case LESS_THAN: { - return TX_DOUBLE_COMPARE(leftDbl, <, rightDbl); + return DOUBLE_COMPARE(leftDbl, <, rightDbl); } case LESS_OR_EQUAL: { - return TX_DOUBLE_COMPARE(leftDbl, <=, rightDbl); + return DOUBLE_COMPARE(leftDbl, <=, rightDbl); } case GREATER_THAN: { - return TX_DOUBLE_COMPARE(leftDbl, >, rightDbl); + return DOUBLE_COMPARE(leftDbl, >, rightDbl); } case GREATER_OR_EQUAL: { - return TX_DOUBLE_COMPARE(leftDbl, >=, rightDbl); + return DOUBLE_COMPARE(leftDbl, >=, rightDbl); } default: {