diff -r 000000000000 -r 6474c204b198 content/base/src/nsAttrValueInlines.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/content/base/src/nsAttrValueInlines.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,220 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsAttrValueInlines_h__ +#define nsAttrValueInlines_h__ + +#include + +#include "nsAttrValue.h" + +struct MiscContainer +{ + typedef nsAttrValue::ValueType ValueType; + + ValueType mType; + // mStringBits points to either nsIAtom* or nsStringBuffer* and is used when + // mType isn't mCSSStyleRule. + // Note eStringBase and eAtomBase is used also to handle the type of + // mStringBits. + uintptr_t mStringBits; + union { + struct { + union { + int32_t mInteger; + nscolor mColor; + uint32_t mEnumValue; + int32_t mPercent; + mozilla::css::StyleRule* mCSSStyleRule; + mozilla::css::URLValue* mURL; + mozilla::css::ImageValue* mImage; + nsAttrValue::AtomArray* mAtomArray; + nsIntMargin* mIntMargin; + const nsSVGAngle* mSVGAngle; + const nsSVGIntegerPair* mSVGIntegerPair; + const nsSVGLength2* mSVGLength; + const mozilla::SVGLengthList* mSVGLengthList; + const mozilla::SVGNumberList* mSVGNumberList; + const nsSVGNumberPair* mSVGNumberPair; + const mozilla::SVGPathData* mSVGPathData; + const mozilla::SVGPointList* mSVGPointList; + const mozilla::SVGAnimatedPreserveAspectRatio* mSVGPreserveAspectRatio; + const mozilla::SVGStringList* mSVGStringList; + const mozilla::SVGTransformList* mSVGTransformList; + const nsSVGViewBox* mSVGViewBox; + }; + uint32_t mRefCount : 31; + uint32_t mCached : 1; + } mValue; + double mDoubleValue; + }; + + MiscContainer() + : mType(nsAttrValue::eColor), + mStringBits(0) + { + MOZ_COUNT_CTOR(MiscContainer); + mValue.mColor = 0; + mValue.mRefCount = 0; + mValue.mCached = 0; + } + + ~MiscContainer() + { + if (IsRefCounted()) { + MOZ_ASSERT(mValue.mRefCount == 0); + MOZ_ASSERT(!mValue.mCached); + } + MOZ_COUNT_DTOR(MiscContainer); + } + + bool GetString(nsAString& aString) const; + + inline bool IsRefCounted() const + { + // Nothing stops us from refcounting (and sharing) other types of + // MiscContainer (except eDoubleValue types) but there's no compelling + // reason to + return mType == nsAttrValue::eCSSStyleRule; + } + + inline int32_t AddRef() { + MOZ_ASSERT(IsRefCounted()); + return ++mValue.mRefCount; + } + + inline int32_t Release() { + MOZ_ASSERT(IsRefCounted()); + return --mValue.mRefCount; + } + + void Cache(); + void Evict(); +}; + + +/** + * Implementation of inline methods + */ + +inline int32_t +nsAttrValue::GetIntegerValue() const +{ + NS_PRECONDITION(Type() == eInteger, "wrong type"); + return (BaseType() == eIntegerBase) + ? GetIntInternal() + : GetMiscContainer()->mValue.mInteger; +} + +inline int16_t +nsAttrValue::GetEnumValue() const +{ + NS_PRECONDITION(Type() == eEnum, "wrong type"); + // We don't need to worry about sign extension here since we're + // returning an int16_t which will cut away the top bits. + return static_cast(( + (BaseType() == eIntegerBase) + ? static_cast(GetIntInternal()) + : GetMiscContainer()->mValue.mEnumValue) + >> NS_ATTRVALUE_ENUMTABLEINDEX_BITS); +} + +inline float +nsAttrValue::GetPercentValue() const +{ + NS_PRECONDITION(Type() == ePercent, "wrong type"); + return ((BaseType() == eIntegerBase) + ? GetIntInternal() + : GetMiscContainer()->mValue.mPercent) + / 100.0f; +} + +inline nsAttrValue::AtomArray* +nsAttrValue::GetAtomArrayValue() const +{ + NS_PRECONDITION(Type() == eAtomArray, "wrong type"); + return GetMiscContainer()->mValue.mAtomArray; +} + +inline mozilla::css::StyleRule* +nsAttrValue::GetCSSStyleRuleValue() const +{ + NS_PRECONDITION(Type() == eCSSStyleRule, "wrong type"); + return GetMiscContainer()->mValue.mCSSStyleRule; +} + +inline mozilla::css::URLValue* +nsAttrValue::GetURLValue() const +{ + NS_PRECONDITION(Type() == eURL, "wrong type"); + return GetMiscContainer()->mValue.mURL; +} + +inline mozilla::css::ImageValue* +nsAttrValue::GetImageValue() const +{ + NS_PRECONDITION(Type() == eImage, "wrong type"); + return GetMiscContainer()->mValue.mImage; +} + +inline double +nsAttrValue::GetDoubleValue() const +{ + NS_PRECONDITION(Type() == eDoubleValue, "wrong type"); + return GetMiscContainer()->mDoubleValue; +} + +inline bool +nsAttrValue::GetIntMarginValue(nsIntMargin& aMargin) const +{ + NS_PRECONDITION(Type() == eIntMarginValue, "wrong type"); + nsIntMargin* m = GetMiscContainer()->mValue.mIntMargin; + if (!m) + return false; + aMargin = *m; + return true; +} + +inline bool +nsAttrValue::IsSVGType(ValueType aType) const +{ + return aType >= eSVGTypesBegin && aType <= eSVGTypesEnd; +} + +inline void +nsAttrValue::SetPtrValueAndType(void* aValue, ValueBaseType aType) +{ + NS_ASSERTION(!(NS_PTR_TO_INT32(aValue) & ~NS_ATTRVALUE_POINTERVALUE_MASK), + "pointer not properly aligned, this will crash"); + mBits = reinterpret_cast(aValue) | aType; +} + +inline void +nsAttrValue::ResetIfSet() +{ + if (mBits) { + Reset(); + } +} + +inline MiscContainer* +nsAttrValue::GetMiscContainer() const +{ + NS_ASSERTION(BaseType() == eOtherBase, "wrong type"); + return static_cast(GetPtr()); +} + +inline int32_t +nsAttrValue::GetIntInternal() const +{ + NS_ASSERTION(BaseType() == eIntegerBase, + "getting integer from non-integer"); + // Make sure we get a signed value. + // Lets hope the optimizer optimizes this into a shift. Unfortunatly signed + // bitshift right is implementaion dependant. + return static_cast(mBits & ~NS_ATTRVALUE_INTEGERTYPE_MASK) / + NS_ATTRVALUE_INTEGERTYPE_MULTIPLIER; +} + +#endif