Bug 798853, style system. r=roc,dbaron a=akeybl
authorMats Palmgren <matspal@gmail.com>
Fri, 02 Nov 2012 00:15:15 +0100
changeset 82068 4bc1f76124369296032816cd34a0675e6d40ccaa
parent 82067 677added3cc5c95643f5948b90f5439cb6a30123
child 82069 821d51ee03bd4b07f2df95ece6f3522da37dfbd0
push id322
push usermpalmgren@mozilla.com
push dateThu, 01 Nov 2012 23:15:27 +0000
reviewersroc, dbaron, akeybl
bugs798853
milestone10.0.11esrpre
Bug 798853, style system. r=roc,dbaron a=akeybl
layout/style/nsCSSValue.cpp
layout/style/nsCSSValue.h
layout/style/nsStyleAnimation.cpp
--- a/layout/style/nsCSSValue.cpp
+++ b/layout/style/nsCSSValue.cpp
@@ -65,16 +65,17 @@ nsCSSValue::nsCSSValue(PRInt32 aValue, n
 }
 
 nsCSSValue::nsCSSValue(float aValue, nsCSSUnit aUnit)
   : mUnit(aUnit)
 {
   NS_ABORT_IF_FALSE(eCSSUnit_Percent <= aUnit, "not a float value");
   if (eCSSUnit_Percent <= aUnit) {
     mValue.mFloat = aValue;
+    MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(mValue.mFloat));
   }
   else {
     mUnit = eCSSUnit_Null;
     mValue.mInt = 0;
   }
 }
 
 nsCSSValue::nsCSSValue(const nsString& aValue, nsCSSUnit aUnit)
@@ -127,16 +128,17 @@ nsCSSValue::nsCSSValue(nsCSSValueGradien
 nsCSSValue::nsCSSValue(const nsCSSValue& aCopy)
   : mUnit(aCopy.mUnit)
 {
   if (mUnit <= eCSSUnit_DummyInherit) {
     // nothing to do, but put this important case first
   }
   else if (eCSSUnit_Percent <= mUnit) {
     mValue.mFloat = aCopy.mValue.mFloat;
+    MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(mValue.mFloat));
   }
   else if (UnitHasStringValue()) {
     mValue.mString = aCopy.mValue.mString;
     mValue.mString->AddRef();
   }
   else if (eCSSUnit_Integer <= mUnit && mUnit <= eCSSUnit_EnumColor) {
     mValue.mInt = aCopy.mValue.mInt;
   }
@@ -343,25 +345,27 @@ void nsCSSValue::SetIntValue(PRInt32 aVa
   }
 }
 
 void nsCSSValue::SetPercentValue(float aValue)
 {
   Reset();
   mUnit = eCSSUnit_Percent;
   mValue.mFloat = aValue;
+  MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(mValue.mFloat));
 }
 
 void nsCSSValue::SetFloatValue(float aValue, nsCSSUnit aUnit)
 {
   NS_ABORT_IF_FALSE(eCSSUnit_Number <= aUnit, "not a float value");
   Reset();
   if (eCSSUnit_Number <= aUnit) {
     mUnit = aUnit;
     mValue.mFloat = aValue;
+    MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(mValue.mFloat));
   }
 }
 
 void nsCSSValue::SetStringValue(const nsString& aValue,
                                 nsCSSUnit aUnit)
 {
   Reset();
   mUnit = aUnit;
--- a/layout/style/nsCSSValue.h
+++ b/layout/style/nsCSSValue.h
@@ -45,16 +45,17 @@
 #include "nsCSSKeywords.h"
 #include "nsCSSProperty.h"
 #include "nsColor.h"
 #include "nsCoord.h"
 #include "nsString.h"
 #include "nsStringBuffer.h"
 #include "nsTArray.h"
 #include "nsStyleConsts.h"
+#include "mozilla/FloatingPoint.h"
 
 class imgIRequest;
 class nsIDocument;
 class nsIPrincipal;
 class nsPresContext;
 class nsIURI;
 
 // Deletes a linked list iteratively to avoid blowing up the stack (bug 456196).
@@ -298,16 +299,17 @@ public:
   {
     NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Percent, "not a percent value");
     return mValue.mFloat;
   }
 
   float GetFloatValue() const
   {
     NS_ABORT_IF_FALSE(eCSSUnit_Number <= mUnit, "not a float value");
+    MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(mValue.mFloat));
     return mValue.mFloat;
   }
 
   float GetAngleValue() const
   {
     NS_ABORT_IF_FALSE(eCSSUnit_Degree <= mUnit &&
                  mUnit <= eCSSUnit_Radian, "not an angle value");
     return mValue.mFloat;
--- a/layout/style/nsStyleAnimation.cpp
+++ b/layout/style/nsStyleAnimation.cpp
@@ -47,16 +47,17 @@
 #include "mozilla/css/StyleRule.h"
 #include "nsString.h"
 #include "nsStyleContext.h"
 #include "nsStyleSet.h"
 #include "nsComputedDOMStyle.h"
 #include "nsCSSParser.h"
 #include "mozilla/css/Declaration.h"
 #include "mozilla/dom/Element.h"
+#include "mozilla/FloatingPoint.h"
 #include "prlog.h"
 #include <math.h>
 #include "gfxMatrix.h"
 #include "gfxQuaternion.h"
 
 using namespace mozilla;
 
 // HELPER METHODS
@@ -696,21 +697,44 @@ inline PRUint8 ClampColor(double aColor)
 {
   if (aColor >= MAX_PACKED_COLOR_COMPONENT)
     return MAX_PACKED_COLOR_COMPONENT;
   if (aColor <= 0.0)
     return 0;
   return NSToIntRound(aColor);
 }
 
+// Ensure that a float/double value isn't NaN by returning zero instead
+// (NaN doesn't have a sign) as a general restriction for floating point
+// values in RestrictValue.
+template<typename T>
+MOZ_ALWAYS_INLINE T
+EnsureNotNan(T aValue)
+{
+  return aValue;
+}
+template<>
+MOZ_ALWAYS_INLINE float
+EnsureNotNan(float aValue)
+{
+  // This would benefit from a MOZ_FLOAT_IS_NaN if we had one.
+  return NS_LIKELY(!MOZ_DOUBLE_IS_NaN(aValue)) ? aValue : 0;
+}
+template<>
+MOZ_ALWAYS_INLINE double
+EnsureNotNan(double aValue)
+{
+  return NS_LIKELY(!MOZ_DOUBLE_IS_NaN(aValue)) ? aValue : 0;
+}
+
 template <typename T>
 T
 RestrictValue(PRUint32 aRestrictions, T aValue)
 {
-  T result = aValue;
+  T result = EnsureNotNan(aValue);
   switch (aRestrictions) {
     case 0:
       break;
     case CSS_PROPERTY_VALUE_NONNEGATIVE:
       if (result < 0) {
         result = 0;
       }
       break;
@@ -3072,22 +3096,24 @@ nsStyleAnimation::Value::Value(nscoord a
   mUnit = eUnit_Coord;
   mValue.mCoord = aLength;
 }
 
 nsStyleAnimation::Value::Value(float aPercent, PercentConstructorType)
 {
   mUnit = eUnit_Percent;
   mValue.mFloat = aPercent;
+  MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(mValue.mFloat));
 }
 
 nsStyleAnimation::Value::Value(float aFloat, FloatConstructorType)
 {
   mUnit = eUnit_Float;
   mValue.mFloat = aFloat;
+  MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(mValue.mFloat));
 }
 
 nsStyleAnimation::Value::Value(nscolor aColor, ColorConstructorType)
 {
   mUnit = eUnit_Color;
   mValue.mColor = aColor;
 }
 
@@ -3109,16 +3135,17 @@ nsStyleAnimation::Value::operator=(const
       mValue.mInt = aOther.mValue.mInt;
       break;
     case eUnit_Coord:
       mValue.mCoord = aOther.mValue.mCoord;
       break;
     case eUnit_Percent:
     case eUnit_Float:
       mValue.mFloat = aOther.mValue.mFloat;
+      MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(mValue.mFloat));
       break;
     case eUnit_Color:
       mValue.mColor = aOther.mValue.mColor;
       break;
     case eUnit_Calc:
       NS_ABORT_IF_FALSE(aOther.mValue.mCSSValue, "values may not be null");
       mValue.mCSSValue = new nsCSSValue(*aOther.mValue.mCSSValue);
       if (!mValue.mCSSValue) {
@@ -3219,24 +3246,26 @@ nsStyleAnimation::Value::SetCoordValue(n
 }
 
 void
 nsStyleAnimation::Value::SetPercentValue(float aPercent)
 {
   FreeValue();
   mUnit = eUnit_Percent;
   mValue.mFloat = aPercent;
+  MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(mValue.mFloat));
 }
 
 void
 nsStyleAnimation::Value::SetFloatValue(float aFloat)
 {
   FreeValue();
   mUnit = eUnit_Float;
   mValue.mFloat = aFloat;
+  MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(mValue.mFloat));
 }
 
 void
 nsStyleAnimation::Value::SetColorValue(nscolor aColor)
 {
   FreeValue();
   mUnit = eUnit_Color;
   mValue.mColor = aColor;