Bug 1309202 - Factor out stylo branch dispatch utilities. r?heycam
MozReview-Commit-ID: 8fLL9nsJDj4
new file mode 100644
--- /dev/null
+++ b/layout/style/ServoUtils.h
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+/* some utilities for stylo */
+
+#ifndef mozilla_ServoUtils_h
+#define mozilla_ServoUtils_h
+
+#include "mozilla/TypeTraits.h"
+
+#ifdef MOZ_STYLO
+# define MOZ_DECL_STYLO_CHECK_METHODS \
+ bool IsGecko() const { return !IsServo(); } \
+ bool IsServo() const { return mType == StyleBackendType::Servo; }
+#else
+# define MOZ_DECL_STYLO_CHECK_METHODS \
+ bool IsGecko() const { return true; } \
+ bool IsServo() const { return false; }
+#endif
+
+/**
+ * Macro used in a base class of |geckotype_| and |servotype_|.
+ * The class should defines |StyleBackendType mType;| itself.
+ */
+#define MOZ_DECL_STYLO_METHODS(geckotype_, servotype_) \
+ MOZ_DECL_STYLO_CHECK_METHODS \
+ inline geckotype_* AsGecko(); \
+ inline servotype_* AsServo(); \
+ inline const geckotype_* AsGecko() const; \
+ inline const servotype_* AsServo() const;
+
+/**
+ * Macro used in inline header of class |type_| with its Gecko and Servo
+ * subclasses named |geckotype_| and |servotype_| correspondingly for
+ * implementing the inline methods defined by MOZ_DECL_STYLO_METHODS.
+ */
+#define MOZ_DEFINE_STYLO_METHODS(type_, geckotype_, servotype_) \
+ geckotype_* type_::AsGecko() { \
+ MOZ_ASSERT(IsGecko()); \
+ return static_cast<geckotype_*>(this); \
+ } \
+ servotype_* type_::AsServo() { \
+ MOZ_ASSERT(IsServo()); \
+ return static_cast<servotype_*>(this); \
+ } \
+ const geckotype_* type_::AsGecko() const { \
+ MOZ_ASSERT(IsGecko()); \
+ return static_cast<const geckotype_*>(this); \
+ } \
+ const servotype_* type_::AsServo() const { \
+ MOZ_ASSERT(IsServo()); \
+ return static_cast<const servotype_*>(this); \
+ }
+
+#define MOZ_STYLO_THIS_TYPE mozilla::RemovePointer<decltype(this)>::Type
+#define MOZ_STYLO_GECKO_TYPE mozilla::RemovePointer<decltype(AsGecko())>::Type
+#define MOZ_STYLO_SERVO_TYPE mozilla::RemovePointer<decltype(AsServo())>::Type
+
+/**
+ * Macro used to forward a method call to the concrete method defined by
+ * the Servo or Gecko implementation. The class of the method using it
+ * should use MOZ_DECL_STYLO_METHODS to define basic stylo methods.
+ */
+#define MOZ_STYLO_FORWARD_CONCRETE(method_, geckoargs_, servoargs_) \
+ static_assert(!mozilla::IsSame<decltype(&MOZ_STYLO_THIS_TYPE::method_), \
+ decltype(&MOZ_STYLO_GECKO_TYPE::method_)> \
+ ::value, "Gecko subclass should define its own " #method_); \
+ static_assert(!mozilla::IsSame<decltype(&MOZ_STYLO_THIS_TYPE::method_), \
+ decltype(&MOZ_STYLO_SERVO_TYPE::method_)> \
+ ::value, "Servo subclass should define its own " #method_); \
+ if (IsServo()) { \
+ return AsServo()->method_ servoargs_; \
+ } \
+ return AsGecko()->method_ geckoargs_;
+
+#define MOZ_STYLO_FORWARD(method_, args_) \
+ MOZ_STYLO_FORWARD_CONCRETE(method_, args_, args_)
+
+#endif // mozilla_ServoUtils_h
--- a/layout/style/StyleSheet.h
+++ b/layout/style/StyleSheet.h
@@ -7,16 +7,17 @@
#ifndef mozilla_StyleSheet_h
#define mozilla_StyleSheet_h
#include "mozilla/css/SheetParsingMode.h"
#include "mozilla/dom/CSSStyleSheetBinding.h"
#include "mozilla/net/ReferrerPolicy.h"
#include "mozilla/StyleBackendType.h"
#include "mozilla/CORSMode.h"
+#include "mozilla/ServoUtils.h"
class nsIDocument;
class nsINode;
namespace mozilla {
class CSSStyleSheet;
class ServoStyleSheet;
@@ -50,32 +51,17 @@ public:
nsIDocument* GetDocument() const { return mDocument; }
/**
* Whether the sheet is complete.
*/
bool IsComplete() const;
void SetComplete();
- bool IsGecko() const { return !IsServo(); }
- bool IsServo() const
- {
-#ifdef MOZ_STYLO
- return mType == StyleBackendType::Servo;
-#else
- return false;
-#endif
- }
-
- // Only safe to call if the caller has verified that that |this| is of the
- // correct type.
- inline CSSStyleSheet* AsGecko();
- inline ServoStyleSheet* AsServo();
- inline const CSSStyleSheet* AsGecko() const;
- inline const ServoStyleSheet* AsServo() const;
+ MOZ_DECL_STYLO_METHODS(CSSStyleSheet, ServoStyleSheet)
inline MozExternalRefCountType AddRef();
inline MozExternalRefCountType Release();
// Whether the sheet is for an inline <style> element.
inline bool IsInline() const;
inline nsIURI* GetSheetURI() const;
--- a/layout/style/StyleSheetInlines.h
+++ b/layout/style/StyleSheetInlines.h
@@ -2,50 +2,23 @@
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 mozilla_StyleSheetInlines_h
#define mozilla_StyleSheetInlines_h
-#include "mozilla/TypeTraits.h"
#include "mozilla/StyleSheetInfo.h"
#include "mozilla/ServoStyleSheet.h"
#include "mozilla/CSSStyleSheet.h"
namespace mozilla {
-CSSStyleSheet*
-StyleSheet::AsGecko()
-{
- MOZ_ASSERT(IsGecko());
- return static_cast<CSSStyleSheet*>(this);
-}
-
-ServoStyleSheet*
-StyleSheet::AsServo()
-{
- MOZ_ASSERT(IsServo());
- return static_cast<ServoStyleSheet*>(this);
-}
-
-const CSSStyleSheet*
-StyleSheet::AsGecko() const
-{
- MOZ_ASSERT(IsGecko());
- return static_cast<const CSSStyleSheet*>(this);
-}
-
-const ServoStyleSheet*
-StyleSheet::AsServo() const
-{
- MOZ_ASSERT(IsServo());
- return static_cast<const ServoStyleSheet*>(this);
-}
+MOZ_DEFINE_STYLO_METHODS(StyleSheet, CSSStyleSheet, ServoStyleSheet)
StyleSheetInfo&
StyleSheet::SheetInfo()
{
if (IsServo()) {
return AsServo()->mSheetInfo;
}
return *AsGecko()->mInner;
@@ -55,40 +28,26 @@ const StyleSheetInfo&
StyleSheet::SheetInfo() const
{
if (IsServo()) {
return AsServo()->mSheetInfo;
}
return *AsGecko()->mInner;
}
-#define FORWARD_CONCRETE(method_, geckoargs_, servoargs_) \
- static_assert(!IsSame<decltype(&StyleSheet::method_), \
- decltype(&CSSStyleSheet::method_)>::value, \
- "CSSStyleSheet should define its own " #method_); \
- static_assert(!IsSame<decltype(&StyleSheet::method_), \
- decltype(&ServoStyleSheet::method_)>::value, \
- "ServoStyleSheet should define its own " #method_); \
- if (IsServo()) { \
- return AsServo()->method_ servoargs_; \
- } \
- return AsGecko()->method_ geckoargs_;
-
-#define FORWARD(method_, args_) FORWARD_CONCRETE(method_, args_, args_)
-
MozExternalRefCountType
StyleSheet::AddRef()
{
- FORWARD(AddRef, ())
+ MOZ_STYLO_FORWARD(AddRef, ())
}
MozExternalRefCountType
StyleSheet::Release()
{
- FORWARD(Release, ())
+ MOZ_STYLO_FORWARD(Release, ())
}
bool
StyleSheet::IsInline() const
{
return !SheetInfo().mOriginalSheetURI;
}
@@ -127,35 +86,36 @@ bool
StyleSheet::IsApplicable() const
{
return !mDisabled && SheetInfo().mComplete;
}
bool
StyleSheet::HasRules() const
{
- FORWARD(HasRules, ())
+ MOZ_STYLO_FORWARD(HasRules, ())
}
void
StyleSheet::SetOwningDocument(nsIDocument* aDocument)
{
- FORWARD(SetOwningDocument, (aDocument))
+ MOZ_STYLO_FORWARD(SetOwningDocument, (aDocument))
}
StyleSheet*
StyleSheet::GetParentSheet() const
{
- FORWARD(GetParentSheet, ())
+ MOZ_STYLO_FORWARD(GetParentSheet, ())
}
void
StyleSheet::AppendStyleSheet(StyleSheet* aSheet)
{
- FORWARD_CONCRETE(AppendStyleSheet, (aSheet->AsGecko()), (aSheet->AsServo()))
+ MOZ_STYLO_FORWARD_CONCRETE(AppendStyleSheet,
+ (aSheet->AsGecko()), (aSheet->AsServo()))
}
nsIPrincipal*
StyleSheet::Principal() const
{
return SheetInfo().mPrincipal;
}
@@ -188,30 +148,27 @@ void
StyleSheet::GetIntegrity(dom::SRIMetadata& aResult) const
{
aResult = SheetInfo().mIntegrity;
}
size_t
StyleSheet::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
- FORWARD(SizeOfIncludingThis, (aMallocSizeOf))
+ MOZ_STYLO_FORWARD(SizeOfIncludingThis, (aMallocSizeOf))
}
#ifdef DEBUG
void
StyleSheet::List(FILE* aOut, int32_t aIndex) const
{
- FORWARD(List, (aOut, aIndex))
+ MOZ_STYLO_FORWARD(List, (aOut, aIndex))
}
#endif
-#undef FORWARD
-#undef FORWARD_CONCRETE
-
inline void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
RefPtr<StyleSheet>& aField,
const char* aName,
uint32_t aFlags = 0)
{
if (aField && aField->IsGecko()) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCallback, aName);
--- a/layout/style/moz.build
+++ b/layout/style/moz.build
@@ -93,16 +93,17 @@ EXPORTS.mozilla += [
'RuleProcessorCache.h',
'ServoBindingHelpers.h',
'ServoBindingList.h',
'ServoBindings.h',
'ServoElementSnapshot.h',
'ServoStyleSet.h',
'ServoStyleSheet.h',
'ServoTypes.h',
+ 'ServoUtils.h',
'SheetType.h',
'StyleAnimationValue.h',
'StyleBackendType.h',
'StyleComplexColor.h',
'StyleContextSource.h',
'StyleSetHandle.h',
'StyleSetHandleInlines.h',
'StyleSheet.h',