| Index: Source/core/css/CSSValue.h
|
| diff --git a/Source/core/css/CSSValue.h b/Source/core/css/CSSValue.h
|
| index 8ffa9dae64a3253b2e171beb2b767a161ff69b4b..a9c8ad8c73687498bba0ea91c67b92facaac1d3f 100644
|
| --- a/Source/core/css/CSSValue.h
|
| +++ b/Source/core/css/CSSValue.h
|
| @@ -22,6 +22,7 @@
|
| #define CSSValue_h
|
|
|
| #include "core/CoreExport.h"
|
| +#include "core/css/CSSPrimitiveValue.h"
|
| #include "core/css/CSSValueObject.h"
|
| #include "platform/heap/Handle.h"
|
| #include "wtf/RefCounted.h"
|
| @@ -40,6 +41,7 @@ public:
|
| : m_data(const_cast<CSSValueObject*>(&cssValueObject))
|
| {
|
| ASSERT(m_data);
|
| + ASSERT(isObject());
|
| ref();
|
| }
|
|
|
| @@ -49,6 +51,7 @@ public:
|
| : m_data(cssValueObject.leakRef())
|
| {
|
| static_assert(WTF::IsSubclass<T, CSSValueObject>::value, "Parameter must be a container for CSSValueObject");
|
| + ASSERT(isObject());
|
| ASSERT(m_data);
|
| }
|
|
|
| @@ -57,6 +60,7 @@ public:
|
| : m_data(cssValueObject.release().leakRef())
|
| {
|
| static_assert(WTF::IsSubclass<T, CSSValueObject>::value, "Parameter must be a container for CSSValueObject");
|
| + ASSERT(isObject());
|
| ASSERT(m_data);
|
| }
|
| #endif
|
| @@ -67,6 +71,13 @@ public:
|
| ref();
|
| }
|
|
|
| + // Implicit conversion from CSSPrimitiveValue.
|
| + CSSValue(const CSSPrimitiveValue& cssPrimitiveValue)
|
| + : m_data(static_cast<CSSValueObject*>(cssPrimitiveValue.get()))
|
| + {
|
| + ref();
|
| + }
|
| +
|
| ~CSSValue()
|
| {
|
| // Although m_data can't be null, a move constructor from NullableCSSValue
|
| @@ -92,18 +103,27 @@ public:
|
| }
|
|
|
| CSSValue(CSSValue&& rhs)
|
| + : m_data(rhs.m_data)
|
| {
|
| - m_data = rhs.m_data;
|
| + rhs.m_data.clear();
|
| }
|
|
|
| bool operator==(const CSSValue& other) const
|
| {
|
| + if (m_data == other.m_data)
|
| + return true;
|
| + if (!isObject() || !other.isObject())
|
| + return false;
|
| return m_data->equals(*other.m_data);
|
| }
|
|
|
| // TODO: Remove this and update callsites to use operator== instead.
|
| bool equals(const CSSValue& other) const
|
| {
|
| + if (m_data == other.m_data)
|
| + return true;
|
| + if (!isObject() || !other.isObject())
|
| + return false;
|
| return m_data->equals(*other.m_data);
|
| }
|
|
|
| @@ -113,46 +133,53 @@ public:
|
| }
|
|
|
| // Methods that proxy to CSSValueObject.
|
| - String cssText() const { return m_data->cssText(); }
|
| - bool hasFailedOrCanceledSubresources() const { return m_data->hasFailedOrCanceledSubresources(); };
|
| - bool isPrimitiveValue() const { return m_data->isPrimitiveValue(); }
|
| - bool isValueList() const { return m_data->isValueList(); }
|
| - bool isBaseValueList() const { return m_data->isBaseValueList(); }
|
| - bool isBorderImageSliceValue() const { return m_data->isBorderImageSliceValue(); }
|
| - bool isCanvasValue() const { return m_data->isCanvasValue(); }
|
| - bool isCursorImageValue() const { return m_data->isCursorImageValue(); }
|
| - bool isCrossfadeValue() const { return m_data->isCrossfadeValue(); }
|
| - bool isFontFeatureValue() const { return m_data->isFontFeatureValue(); }
|
| - bool isFontFaceSrcValue() const { return m_data->isFontFaceSrcValue(); }
|
| - bool isFunctionValue() const { return m_data->isFunctionValue(); }
|
| - bool isImageGeneratorValue() const { return m_data->isImageGeneratorValue(); }
|
| - bool isGradientValue() const { return m_data->isGradientValue(); }
|
| - bool isImageSetValue() const { return m_data->isImageSetValue(); }
|
| - bool isImageValue() const { return m_data->isImageValue(); }
|
| - bool isImplicitInitialValue() const { return m_data->isImplicitInitialValue(); };
|
| - bool isInheritedValue() const { return m_data->isInheritedValue(); };
|
| - bool isInitialValue() const { return m_data->isInitialValue(); };
|
| - bool isUnsetValue() const { return m_data->isUnsetValue(); };
|
| - bool isCSSWideKeyword() const { return m_data->isCSSWideKeyword(); };
|
| - bool isLinearGradientValue() const { return m_data->isLinearGradientValue(); };
|
| - bool isPathValue() const { return m_data->isPathValue(); };
|
| - bool isRadialGradientValue() const { return m_data->isRadialGradientValue(); };
|
| - bool isReflectValue() const { return m_data->isReflectValue(); };
|
| - bool isShadowValue() const { return m_data->isShadowValue(); };
|
| - bool isCubicBezierTimingFunctionValue() const { return m_data->isCubicBezierTimingFunctionValue(); };
|
| - bool isStepsTimingFunctionValue() const { return m_data->isStepsTimingFunctionValue(); };
|
| - bool isLineBoxContainValue() const { return m_data->isLineBoxContainValue(); };
|
| - bool isCalcValue() const { return m_data->isCalcValue(); };
|
| - bool isGridTemplateAreasValue() const { return m_data->isGridTemplateAreasValue(); };
|
| - bool isSVGDocumentValue() const { return m_data->isSVGDocumentValue(); };
|
| - bool isContentDistributionValue() const { return m_data->isContentDistributionValue(); };
|
| - bool isUnicodeRangeValue() const { return m_data->isUnicodeRangeValue(); };
|
| - bool isGridLineNamesValue() const { return m_data->isGridLineNamesValue(); };
|
| + String cssText() const
|
| + {
|
| + if (isObject())
|
| + return m_data->cssText();
|
| + return CSSPrimitiveValue(reinterpret_cast<CSSPrimitiveValue::CSSLargePrimitiveValue*>(m_data.get())).cssText();
|
| + }
|
| +
|
| + bool hasFailedOrCanceledSubresources() const { return isObject() ? m_data->hasFailedOrCanceledSubresources() : false; };
|
| + bool isPrimitiveValue() const { return isObject() ? m_data->isPrimitiveValue() : true; }
|
| + bool isValueList() const { return isObject() ? m_data->isValueList() : false; }
|
| + bool isBaseValueList() const { return isObject() ? m_data->isBaseValueList() : false; }
|
| + bool isBorderImageSliceValue() const { return isObject() ? m_data->isBorderImageSliceValue() : false; }
|
| + bool isCanvasValue() const { return isObject() ? m_data->isCanvasValue() : false; }
|
| + bool isCursorImageValue() const { return isObject() ? m_data->isCursorImageValue() : false; }
|
| + bool isCrossfadeValue() const { return isObject() ? m_data->isCrossfadeValue() : false; }
|
| + bool isFontFeatureValue() const { return isObject() ? m_data->isFontFeatureValue(): false; }
|
| + bool isFontFaceSrcValue() const { return isObject() ? m_data->isFontFaceSrcValue(): false; }
|
| + bool isFunctionValue() const { return isObject() ? m_data->isFunctionValue(): false; }
|
| + bool isImageGeneratorValue() const { return isObject() ? m_data->isImageGeneratorValue(): false; }
|
| + bool isGradientValue() const { return isObject() ? m_data->isGradientValue(): false; }
|
| + bool isImageSetValue() const { return isObject() ? m_data->isImageSetValue(): false; }
|
| + bool isImageValue() const { return isObject() ? m_data->isImageValue(): false; }
|
| + bool isImplicitInitialValue() const { return isObject() ? m_data->isImplicitInitialValue(): false; }
|
| + bool isInheritedValue() const { return isObject() ? m_data->isInheritedValue(): false; }
|
| + bool isInitialValue() const { return isObject() ? m_data->isInitialValue(): false; }
|
| + bool isUnsetValue() const { return isObject() ? m_data->isUnsetValue(): false; }
|
| + bool isCSSWideKeyword() const { return isObject() ? m_data->isCSSWideKeyword(): false; }
|
| + bool isLinearGradientValue() const { return isObject() ? m_data->isLinearGradientValue(): false; }
|
| + bool isPathValue() const { return isObject() ? m_data->isPathValue(): false; }
|
| + bool isRadialGradientValue() const { return isObject() ? m_data->isRadialGradientValue(): false; }
|
| + bool isReflectValue() const { return isObject() ? m_data->isReflectValue(): false; }
|
| + bool isShadowValue() const { return isObject() ? m_data->isShadowValue(): false; }
|
| + bool isCubicBezierTimingFunctionValue() const { return isObject() ? m_data->isCubicBezierTimingFunctionValue(): false; }
|
| + bool isStepsTimingFunctionValue() const { return isObject() ? m_data->isStepsTimingFunctionValue(): false; }
|
| + bool isLineBoxContainValue() const { return isObject() ? m_data->isLineBoxContainValue(): false; }
|
| + bool isCalcValue() const { return isObject() ? m_data->isCalcValue(): false; }
|
| + bool isGridTemplateAreasValue() const { return isObject() ? m_data->isGridTemplateAreasValue(): false; }
|
| + bool isSVGDocumentValue() const { return isObject() ? m_data->isSVGDocumentValue(): false; }
|
| + bool isContentDistributionValue() const { return isObject() ? m_data->isContentDistributionValue(): false; }
|
| + bool isUnicodeRangeValue() const { return isObject() ? m_data->isUnicodeRangeValue(): false; }
|
| + bool isGridLineNamesValue() const { return isObject() ? m_data->isGridLineNamesValue(): false; }
|
|
|
| DEFINE_INLINE_TRACE()
|
| {
|
| ASSERT(m_data);
|
| - visitor->trace(m_data);
|
| + if (isObject())
|
| + visitor->trace(m_data);
|
| }
|
|
|
| // Only for use by the toFooCSSValue() macros. Don't use this.
|
| @@ -170,7 +197,7 @@ private:
|
| void ref() const
|
| {
|
| #if !ENABLE(OILPAN)
|
| - if (m_data)
|
| + if (m_data && isObject())
|
| m_data->ref();
|
| #endif
|
| }
|
| @@ -178,11 +205,16 @@ private:
|
| void deref() const
|
| {
|
| #if !ENABLE(OILPAN)
|
| - if (m_data)
|
| + if (m_data && isObject())
|
| m_data->deref();
|
| #endif
|
| }
|
|
|
| + bool isObject() const
|
| + {
|
| + return !(*reinterpret_cast<const uintptr_t*>(&m_data) & 1);
|
| + }
|
| +
|
| RawPtrWillBeMember<CSSValueObject> m_data;
|
| };
|
|
|
| @@ -238,18 +270,24 @@ public:
|
| }
|
|
|
| NullableCSSValue(NullableCSSValue&& rhs)
|
| + : m_data(rhs.m_data)
|
| {
|
| - m_data = rhs.m_data;
|
| - rhs.m_data = nullptr;
|
| + rhs.m_data.clear();
|
| }
|
|
|
| + // Implicit conversion from CSSPrimitiveValue.
|
| + NullableCSSValue(const CSSPrimitiveValue& cssPrimitiveValue)
|
| + : m_data(static_cast<CSSValueObject*>(cssPrimitiveValue.get()))
|
| + {
|
| + ref();
|
| + }
|
|
|
| ~NullableCSSValue()
|
| {
|
| deref();
|
| };
|
|
|
| - operator bool() const
|
| + explicit operator bool() const
|
| {
|
| return m_data;
|
| }
|
| @@ -271,10 +309,14 @@ public:
|
|
|
| bool operator==(const NullableCSSValue& rhs) const
|
| {
|
| + if (m_data == rhs.m_data)
|
| + return true;
|
| + if (!isObject() || (rhs && !rhs.isObject()))
|
| + return false;
|
| return m_data ? rhs.m_data && m_data->equals(*rhs.m_data) : !bool(rhs.m_data);
|
| }
|
|
|
| - bool operator!=(const NullableCSSValue& rhs)
|
| + bool operator!=(const NullableCSSValue& rhs) const
|
| {
|
| return !(*this == rhs);
|
| }
|
| @@ -311,7 +353,8 @@ public:
|
|
|
| DEFINE_INLINE_TRACE()
|
| {
|
| - visitor->trace(m_data);
|
| + if (isObject())
|
| + visitor->trace(m_data);
|
| }
|
|
|
| // Only for use by the toFooCSSValue() macros. Don't use this.
|
| @@ -326,7 +369,7 @@ private:
|
| void ref() const
|
| {
|
| #if !ENABLE(OILPAN)
|
| - if (m_data)
|
| + if (m_data && isObject())
|
| m_data->ref();
|
| #endif
|
| }
|
| @@ -334,17 +377,23 @@ private:
|
| void deref() const
|
| {
|
| #if !ENABLE(OILPAN)
|
| - if (m_data)
|
| + if (m_data && isObject())
|
| m_data->deref();
|
| #endif
|
| }
|
|
|
| + bool isObject() const
|
| + {
|
| + return !(*reinterpret_cast<const uintptr_t*>(&m_data) & 1);
|
| + }
|
| +
|
| RawPtrWillBeMember<CSSValueObject> m_data;
|
| };
|
|
|
| static_assert(sizeof(CSSValue) == sizeof(void*), "CSSValue should be pointer-sized");
|
| static_assert(sizeof(NullableCSSValue) == sizeof(void*), "CSSValue should be pointer-sized");
|
| static_assert(sizeof(CSSValue) == sizeof(NullableCSSValue), "Both CSSValue containers must contain the same data");
|
| +static_assert(sizeof(CSSValue) == sizeof(CSSPrimitiveValue), "Both CSSValue and CSSPrimitiveValue must contain the same data");
|
|
|
| template<size_t inlineCapacity>
|
| inline bool compareCSSValueVector(const WillBeHeapVector<CSSValue, inlineCapacity>& firstVector, const WillBeHeapVector<CSSValue, inlineCapacity>& secondVector)
|
| @@ -378,6 +427,24 @@ inline bool compareCSSValueVector(const WillBeHeapVector<CSSValue, inlineCapacit
|
| return static_cast<thisType*>(value.get()); \
|
| }
|
|
|
| +inline const CSSPrimitiveValue& toCSSPrimitiveValue(const CSSValue& value)
|
| +{
|
| + ASSERT_WITH_SECURITY_IMPLICATION(value.isPrimitiveValue());
|
| + return *reinterpret_cast<const CSSPrimitiveValue*>(&value);
|
| +}
|
| +inline const CSSPrimitiveValue& toCSSPrimitiveValue(const NullableCSSValue& value)
|
| +{
|
| + ASSERT_WITH_SECURITY_IMPLICATION(value && value->isPrimitiveValue());
|
| + return *reinterpret_cast<const CSSPrimitiveValue*>(&value);
|
| +}
|
| +/*
|
| +inline CSSPrimitiveValue& toCSSPrimitiveValue(const CSSValue& value)
|
| +{
|
| + ASSERT_WITH_SECURITY_IMPLICATION(value.isPrimitiveValue());
|
| + return *const_cast<CSSPrimitiveValue*>(reinterpret_cast<const CSSPrimitiveValue*>(&value));
|
| +}
|
| +*/
|
| +
|
| } // namespace blink
|
|
|
| WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::CSSValue);
|
|
|