| Index: Source/core/css/CSSPrimitiveValue.h
|
| diff --git a/Source/core/css/CSSPrimitiveValue.h b/Source/core/css/CSSPrimitiveValue.h
|
| index a810b39136c13da67a088033ce8e128cc5ad6347..9f84a36b9bf1b567c16b5a5a641ccb56570fc337 100644
|
| --- a/Source/core/css/CSSPrimitiveValue.h
|
| +++ b/Source/core/css/CSSPrimitiveValue.h
|
| @@ -109,35 +109,35 @@ public:
|
| CSS_S = 15,
|
| CSS_HZ = 16,
|
| CSS_KHZ = 17,
|
| - CSS_CUSTOM_IDENT = 19,
|
| - CSS_URI = 20,
|
| - CSS_IDENT = 21,
|
| - CSS_ATTR = 22,
|
| - CSS_COUNTER = 23,
|
| - CSS_RECT = 24,
|
| - CSS_RGBCOLOR = 25,
|
| - CSS_VW = 26,
|
| - CSS_VH = 27,
|
| - CSS_VMIN = 28,
|
| - CSS_VMAX = 29,
|
| - CSS_DPPX = 30,
|
| - CSS_DPI = 31,
|
| - CSS_DPCM = 32,
|
| - CSS_FR = 33,
|
| - CSS_INTEGER = 34,
|
| - CSS_PAIR = 100,
|
| - CSS_TURN = 107,
|
| - CSS_REMS = 108,
|
| - CSS_CHS = 109,
|
| - CSS_SHAPE = 111,
|
| - CSS_QUAD = 112,
|
| - CSS_CALC = 113,
|
| - CSS_CALC_PERCENTAGE_WITH_NUMBER = 114,
|
| - CSS_CALC_PERCENTAGE_WITH_LENGTH = 115,
|
| - CSS_STRING = 116,
|
| - CSS_PROPERTY_ID = 117,
|
| - CSS_VALUE_ID = 118,
|
| - CSS_QEM = 119
|
| + CSS_CUSTOM_IDENT = 18,
|
| + CSS_URI = 19,
|
| + CSS_IDENT = 20,
|
| + CSS_ATTR = 21,
|
| + CSS_COUNTER = 22,
|
| + CSS_RECT = 23,
|
| + CSS_RGBCOLOR = 24,
|
| + CSS_VW = 25,
|
| + CSS_VH = 26,
|
| + CSS_VMIN = 27,
|
| + CSS_VMAX = 28,
|
| + CSS_DPPX = 29,
|
| + CSS_DPI = 30,
|
| + CSS_DPCM = 31,
|
| + CSS_FR = 32,
|
| + CSS_INTEGER = 33,
|
| + CSS_PAIR = 34,
|
| + CSS_TURN = 35,
|
| + CSS_REMS = 36,
|
| + CSS_CHS = 37,
|
| + CSS_SHAPE = 38,
|
| + CSS_QUAD = 39,
|
| + CSS_CALC = 40,
|
| + CSS_CALC_PERCENTAGE_WITH_NUMBER = 41,
|
| + CSS_CALC_PERCENTAGE_WITH_LENGTH = 42,
|
| + CSS_STRING = 43,
|
| + CSS_PROPERTY_ID = 44,
|
| + CSS_VALUE_ID = 45,
|
| + CSS_QEM = 46
|
| };
|
|
|
| enum LengthUnitType {
|
| @@ -159,6 +159,123 @@ public:
|
| typedef Vector<double, CSSPrimitiveValue::LengthUnitTypeCount> CSSLengthArray;
|
| typedef BitVector CSSLengthTypeArray;
|
|
|
| + struct CSSTaggedPtrValue {
|
| + // Variables for accessing parts of the tagged pointer.
|
| + // 32 bits = <value 25 bits><type 6 bits><tag 1 bit>
|
| + // 64 bits = <value 57 bits><type 6 bits><tag 1 bit>
|
| +#if CPU(32BIT)
|
| + static const uint doubleShiftAmount = 32 + 7;
|
| + static const uint64_t mantissaTruncationMask = 0x7fffffffff;
|
| +#elif CPU(64BIT)
|
| + static const uint doubleShiftAmount = 7;
|
| + static const uint64_t mantissaTruncationMask = 0x7f;
|
| +#endif
|
| +
|
| + unsigned flag : 1;
|
| + unsigned type : 6;
|
| +#if CPU(32BIT)
|
| + unsigned long long valueRaw : 25;
|
| +#elif CPU(64BIT)
|
| + unsigned long long valueRaw : 57;
|
| +#endif
|
| +
|
| + typedef struct {
|
| + unsigned red : 8;
|
| + unsigned green : 8;
|
| + unsigned blue : 8;
|
| +#if CPU(32BIT)
|
| + unsigned alpha : 1;
|
| +#elif CPU(64BIT)
|
| + unsigned alpha : 8;
|
| +#endif
|
| + } packedColor;
|
| +
|
| +
|
| + // Returns true if value can be stored in the value field of the tagged pointer
|
| + // without losing information.
|
| + inline static bool fitsWithoutDataLoss(double value)
|
| + {
|
| + union {
|
| + double asDouble;
|
| + uint64_t asBits;
|
| + } interpretableValue;
|
| + interpretableValue.asDouble = value;
|
| + return (interpretableValue.asBits & mantissaTruncationMask) == 0;
|
| + }
|
| +
|
| + inline static bool fitsWithoutDataLoss(RGBA32 color)
|
| + {
|
| +#if CPU(32BIT)
|
| + return alphaChannel(color) == 0 || alphaChannel(color) == 255;
|
| +#elif CPU(64BIT)
|
| + return true;
|
| +#endif
|
| + }
|
| +
|
| + // Convenience methods for getting/setting the value field, which is truncated.
|
| + inline double getValue() const
|
| + {
|
| + uint64_t shiftedValue = valueRaw;
|
| + shiftedValue = shiftedValue << doubleShiftAmount;
|
| + return *reinterpret_cast<double*>(&shiftedValue);
|
| + }
|
| +
|
| + inline RGBA32 getColorValue() const
|
| + {
|
| + uintptr_t valueRawVar = valueRaw;
|
| + packedColor color = *reinterpret_cast<packedColor*>(&valueRawVar);
|
| + int alpha = color.alpha;
|
| +#if CPU(32BIT)
|
| + alpha = color.alpha == 1 ? 255 : 0;
|
| +#endif
|
| + return makeRGBA(color.red, color.green, color.blue, alpha);
|
| + }
|
| +
|
| + inline CSSPropertyID getPropertyIDValue() const
|
| + {
|
| + return static_cast<CSSPropertyID>(valueRaw);
|
| + }
|
| +
|
| + inline CSSValueID getValueIDValue() const
|
| + {
|
| + return static_cast<CSSValueID>(valueRaw);
|
| + }
|
| +
|
| + inline void setValue(double value)
|
| + {
|
| + union {
|
| + double asDouble;
|
| + uint64_t asBits;
|
| + } interpretableValue;
|
| + interpretableValue.asDouble = value;
|
| + valueRaw = interpretableValue.asBits >> doubleShiftAmount;
|
| + }
|
| +
|
| + inline void setValue(RGBA32 value)
|
| + {
|
| + packedColor color;
|
| + color.red = static_cast<uintptr_t>(redChannel(value));
|
| + color.green = static_cast<uintptr_t>(greenChannel(value));
|
| + color.blue = static_cast<uintptr_t>(blueChannel(value));
|
| +#if CPU(32BIT)
|
| + color.alpha = static_cast<uintptr_t>(alphaChannel(value) == 255 ? 1 : 0);
|
| +#elif CPU(64BIT)
|
| + color.alpha = static_cast<uintptr_t>(alphaChannel(value));
|
| +#endif
|
| + valueRaw = *reinterpret_cast<uintptr_t*>(&color);
|
| + }
|
| +
|
| + inline void setValue(CSSPropertyID propertyID)
|
| + {
|
| + valueRaw = static_cast<uintptr_t>(propertyID);
|
| + }
|
| +
|
| + inline void setValue(CSSValueID valueID)
|
| + {
|
| + valueRaw = static_cast<uintptr_t>(valueID);
|
| + }
|
| + };
|
| +
|
| // No methods here, don't use this. It's just for large value storage.
|
| // IMPORTANT: You should never actually make one of these outside the parser.
|
| class CSSLargePrimitiveValue final : public CSSValueObject {
|
| @@ -206,6 +323,12 @@ public:
|
| CSSPrimitiveValueData m_value;
|
| };
|
|
|
| + explicit CSSPrimitiveValue(CSSTaggedPtrValue taggedPtr)
|
| + : m_rawValue(taggedPtr)
|
| + {
|
| + ASSERT(!isObject());
|
| + }
|
| +
|
| explicit CSSPrimitiveValue(const CSSLargePrimitiveValue* object)
|
| : m_rawValue(const_cast<CSSLargePrimitiveValue*>(object))
|
| {
|
| @@ -219,7 +342,7 @@ public:
|
|
|
|
|
| CSSPrimitiveValue(const CSSPrimitiveValue& other)
|
| - : m_rawValue(other.m_rawValue)
|
| + : m_rawValue(other.m_rawValue.asPtr)
|
| {
|
| ref();
|
| }
|
| @@ -240,7 +363,7 @@ public:
|
|
|
| CSSLargePrimitiveValue* get() const
|
| {
|
| - return m_rawValue;
|
| + return m_rawValue.asPtr;
|
| }
|
|
|
| void accumulateLengthArray(CSSLengthArray&, double multiplier = 1) const;
|
| @@ -309,18 +432,41 @@ public:
|
|
|
| static CSSPrimitiveValue createIdentifier(CSSValueID valueID)
|
| {
|
| - return CSSPrimitiveValue(adoptRefWillBeNoop(new CSSLargePrimitiveValue(valueID)));
|
| + CSSTaggedPtrValue taggedPointer;
|
| + taggedPointer.flag = 1;
|
| + taggedPointer.type = CSS_VALUE_ID;
|
| + taggedPointer.setValue(valueID);
|
| + return CSSPrimitiveValue(taggedPointer);
|
| }
|
| +
|
| static CSSPrimitiveValue createIdentifier(CSSPropertyID propertyID)
|
| {
|
| - return CSSPrimitiveValue(adoptRefWillBeNoop(new CSSLargePrimitiveValue(propertyID)));
|
| + CSSTaggedPtrValue taggedPointer;
|
| + taggedPointer.flag = 1;
|
| + taggedPointer.type = CSS_PROPERTY_ID;
|
| + taggedPointer.setValue(propertyID);
|
| + return CSSPrimitiveValue(taggedPointer);
|
| }
|
| static CSSPrimitiveValue createColor(RGBA32 rgbValue)
|
| {
|
| + if (CSSTaggedPtrValue::fitsWithoutDataLoss(rgbValue)) {
|
| + CSSTaggedPtrValue taggedPointer;
|
| + taggedPointer.flag = 1;
|
| + taggedPointer.type = CSS_RGBCOLOR;
|
| + taggedPointer.setValue(rgbValue);
|
| + return CSSPrimitiveValue(taggedPointer);
|
| + }
|
| return CSSPrimitiveValue(adoptRefWillBeNoop(new CSSLargePrimitiveValue(rgbValue)));
|
| }
|
| static CSSPrimitiveValue create(double value, UnitType type)
|
| {
|
| + if (CSSTaggedPtrValue::fitsWithoutDataLoss(value)) {
|
| + CSSTaggedPtrValue taggedPointer;
|
| + taggedPointer.flag = 1;
|
| + taggedPointer.type = type;
|
| + taggedPointer.setValue(value);
|
| + return CSSPrimitiveValue(taggedPointer);
|
| + }
|
| return CSSPrimitiveValue(adoptRefWillBeNoop(new CSSLargePrimitiveValue(value, type)));
|
| }
|
| static CSSPrimitiveValue create(const String& value, UnitType type)
|
| @@ -391,7 +537,12 @@ public:
|
| String customCSSText() const;
|
| String cssText() const { return customCSSText(); }
|
|
|
| - bool isQuirkValue() const { return m_rawValue->m_isQuirkValue; }
|
| + bool isQuirkValue() const
|
| + {
|
| + if (!isObject())
|
| + return false;
|
| + return m_rawValue.asPtr->m_isQuirkValue;
|
| + }
|
|
|
| bool equals(const CSSPrimitiveValue) const;
|
|
|
| @@ -405,21 +556,22 @@ public:
|
| DEFINE_INLINE_TRACE()
|
| {
|
| visitor->trace(m_rawValue);
|
| - m_rawValue->traceAfterDispatch(visitor);
|
| }
|
|
|
| private:
|
| void ref() const
|
| {
|
| #if !ENABLE(OILPAN)
|
| - m_rawValue->ref();
|
| + if (isObject())
|
| + m_rawValue.asPtr->ref();
|
| #endif
|
| }
|
|
|
| void deref() const
|
| {
|
| #if !ENABLE(OILPAN)
|
| - m_rawValue->deref();
|
| + if (isObject())
|
| + m_rawValue.asPtr->deref();
|
| #endif
|
| }
|
|
|
| @@ -429,22 +581,59 @@ private:
|
|
|
| double computeLengthDouble(const CSSToLengthConversionData&);
|
|
|
| - RawPtrWillBeMember<CSSLargePrimitiveValue> m_rawValue;
|
| + union CSSPrimitivePointerValue {
|
| + CSSTaggedPtrValue asTaggedPtr;
|
| + RawPtrWillBeMember<CSSLargePrimitiveValue> asPtr;
|
| +
|
| + CSSPrimitivePointerValue(CSSLargePrimitiveValue* ptr) : asPtr(ptr) { }
|
| + CSSPrimitivePointerValue(CSSTaggedPtrValue taggedPtr) : asTaggedPtr(taggedPtr) { }
|
| +
|
| + DEFINE_INLINE_TRACE()
|
| + {
|
| + if (!(reinterpret_cast<uintptr_t>(asPtr.get()) & 1)) {
|
| + visitor->trace(asPtr);
|
| + asPtr->traceAfterDispatch(visitor);
|
| + }
|
| + }
|
| + } m_rawValue;
|
| + static_assert(sizeof(m_rawValue) == sizeof(void*), "The tagged pointer field in CSSPrimitiveValue must be the size of a pointer");
|
| +
|
| + bool isObject() const
|
| + {
|
| + return m_rawValue.asTaggedPtr.flag == 0;
|
| + }
|
|
|
| // Getters/setters for inner class.
|
| - CSSPrimitiveValueData value() const { return m_rawValue->m_value; }
|
| - UnitType type() const { return static_cast<UnitType>(m_rawValue->m_primitiveUnitType); }
|
| - bool hasCachedCSSText() const { return m_rawValue->m_hasCachedCSSText; }
|
| -
|
| - void setValue(CSSPrimitiveValueData value) { m_rawValue->m_value = value; }
|
| - void setType(UnitType primitiveUnitType) { m_rawValue->m_primitiveUnitType = static_cast<unsigned>(primitiveUnitType); }
|
| - void setHasCachedCSSText(bool hasCachedCSSText) const { m_rawValue->m_hasCachedCSSText = hasCachedCSSText; }
|
| - void setIsQuirkValue(bool isQuirkValue) { m_rawValue->m_isQuirkValue = isQuirkValue; }
|
| + CSSPrimitiveValueData value() const
|
| + {
|
| + if (isObject())
|
| + return m_rawValue.asPtr->m_value;
|
| +
|
| + CSSPrimitiveValueData result;
|
| + if (m_rawValue.asTaggedPtr.type == CSS_RGBCOLOR)
|
| + result.rgbcolor = m_rawValue.asTaggedPtr.getColorValue();
|
| + else if (m_rawValue.asTaggedPtr.type == CSS_PROPERTY_ID)
|
| + result.propertyID = m_rawValue.asTaggedPtr.getPropertyIDValue();
|
| + else if (m_rawValue.asTaggedPtr.type == CSS_VALUE_ID)
|
| + result.valueID = m_rawValue.asTaggedPtr.getValueIDValue();
|
| + else
|
| + result.num = m_rawValue.asTaggedPtr.getValue();
|
| + return result;
|
| + }
|
| +
|
| + UnitType type() const
|
| + {
|
| + if (isObject())
|
| + return static_cast<UnitType>(m_rawValue.asPtr->m_primitiveUnitType);
|
| + return static_cast<UnitType>(m_rawValue.asTaggedPtr.type);
|
| + }
|
| };
|
|
|
| typedef CSSPrimitiveValue::CSSLengthArray CSSLengthArray;
|
| typedef CSSPrimitiveValue::CSSLengthTypeArray CSSLengthTypeArray;
|
|
|
| +static_assert(sizeof(CSSPrimitiveValue) == sizeof(void*), "CSSPrimitiveValue must be the size of a pointer");
|
| +
|
| } // namespace blink
|
|
|
| #endif // CSSPrimitiveValue_h
|
|
|