Bug 1309202 - Factor out stylo branch dispatch utilities. r?heycam draft
authorXidorn Quan <me@upsuper.org>
Wed, 12 Oct 2016 00:15:53 +1100
changeset 423641 fac14e4446a32e6e225e4b405a574225a990b510
parent 423640 58ef5f14683a8e666749cb05711d1a054955aa88
child 424538 0e404506082138f42617bdea433910e9a816f9d6
child 424777 4279a4cf097bc4f433b2cea42721b6fc20ded1ea
push id31950
push userxquan@mozilla.com
push dateTue, 11 Oct 2016 13:16:32 +0000
reviewersheycam
bugs1309202
milestone52.0a1
Bug 1309202 - Factor out stylo branch dispatch utilities. r?heycam MozReview-Commit-ID: 8fLL9nsJDj4
layout/style/ServoUtils.h
layout/style/StyleSheet.h
layout/style/StyleSheetInlines.h
layout/style/moz.build
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',