Bug 1498755 - Part 11: Move Gecko borrowed FFI types to a separate header file r=emilio
authorCameron McCormack <cam@mcc.id.au>
Sun, 14 Oct 2018 00:06:13 +0000
changeset 489543 8819dd315519624abe75cb340aa1ae8cfd62ca86
parent 489542 5adb545ddcfd3f1275a6ad5ea62bb2b9588a48dc
child 489544 6609c511837ddeb4a88ba6a5341b26202ebe316e
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersemilio
bugs1498755
milestone64.0a1
Bug 1498755 - Part 11: Move Gecko borrowed FFI types to a separate header file r=emilio Depends on D8652 Differential Revision: https://phabricator.services.mozilla.com/D8653
layout/style/BorrowedTypeList.h
layout/style/ServoBindingTypes.h
layout/style/ServoBindings.h
layout/style/ServoBindings.toml
layout/style/StyleSheetInfo.h
layout/style/moz.build
servo/components/style/build_gecko.rs
servo/components/style/gecko/data.rs
servo/components/style/gecko/media_queries.rs
servo/ports/geckolib/glue.rs
new file mode 100644
--- /dev/null
+++ b/layout/style/BorrowedTypeList.h
@@ -0,0 +1,52 @@
+/* -*- 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/. */
+
+/* a list of Gecko types used across bindings, for preprocessing */
+
+// There are two macros:
+//
+//   GECKO_BORROWED_TYPE(gecko_type, ffi_type_name)
+//   GECKO_BORROWED_MUT_TYPE(gecko_type, ffi_type_name)
+//
+// GECKO_BORROWED_TYPE will generated Borrowed and BorrowedOrNull types.
+//
+// GECKO_BORROWED_MUT_TYPE will generate those and the BorrowedMut &
+// BorrowedMutOrNull types.
+//
+// The first argument is the Gecko C++ type name.  This must be a type
+// that is in scope in ServoBindingTypes.h; forward declarations may need
+// to be added there.
+//
+// The second argument is the name of a typedef that will be generated,
+// equivalent to the actual C++ type.  This name will be used as the basis
+// for the generated borrowed type names to be used in FFI signatures in
+// C++ and Rust.  The convention for this name is "RawGecko{Type}", where
+// {Type} is the name of the C++ type or something close to it.
+//
+// See the comment at the top of ServoBindingTypes.h for how to use these.
+
+GECKO_BORROWED_TYPE(mozilla::dom::Element, RawGeckoElement)
+GECKO_BORROWED_TYPE(nsIDocument, RawGeckoDocument)
+GECKO_BORROWED_TYPE(nsINode, RawGeckoNode)
+GECKO_BORROWED_TYPE(nsPresContext, RawGeckoPresContext)
+GECKO_BORROWED_TYPE(nsXBLBinding, RawGeckoXBLBinding)
+GECKO_BORROWED_TYPE_MUT(mozilla::AnimationPropertySegment, RawGeckoAnimationPropertySegment)
+GECKO_BORROWED_TYPE_MUT(mozilla::ComputedTiming, RawGeckoComputedTiming)
+GECKO_BORROWED_TYPE_MUT(mozilla::dom::StyleChildrenIterator, RawGeckoStyleChildrenIterator)
+GECKO_BORROWED_TYPE_MUT(mozilla::GfxMatrix4x4, RawGeckoGfxMatrix4x4)
+GECKO_BORROWED_TYPE_MUT(mozilla::ServoElementSnapshot, ServoElementSnapshot)
+GECKO_BORROWED_TYPE_MUT(mozilla::URLExtraData, RawGeckoURLExtraData)
+GECKO_BORROWED_TYPE_MUT(nsCSSPropertyIDSet, nsCSSPropertyIDSet)
+GECKO_BORROWED_TYPE_MUT(nsCSSValue, nsCSSValue)
+GECKO_BORROWED_TYPE_MUT(nsStyleAutoArray<mozilla::StyleAnimation>, RawGeckoStyleAnimationList)
+GECKO_BORROWED_TYPE_MUT(nsTArray<const RawServoStyleRule*>, RawGeckoServoStyleRuleList)
+GECKO_BORROWED_TYPE_MUT(nsTArray<mozilla::ComputedKeyframeValues>, RawGeckoComputedKeyframeValuesList)
+GECKO_BORROWED_TYPE_MUT(nsTArray<mozilla::Keyframe>, RawGeckoKeyframeList)
+GECKO_BORROWED_TYPE_MUT(nsTArray<mozilla::PropertyValuePair>, RawGeckoPropertyValuePairList)
+GECKO_BORROWED_TYPE_MUT(nsTArray<nsCSSPropertyID>, RawGeckoCSSPropertyIDList)
+GECKO_BORROWED_TYPE_MUT(nsTArray<nsFontFaceRuleContainer>, RawGeckoFontFaceRuleList)
+GECKO_BORROWED_TYPE_MUT(nsTArray<RefPtr<RawServoAnimationValue>>, RawGeckoServoAnimationValueList)
+GECKO_BORROWED_TYPE_MUT(nsTimingFunction, nsTimingFunction)
--- a/layout/style/ServoBindingTypes.h
+++ b/layout/style/ServoBindingTypes.h
@@ -151,194 +151,90 @@
 #include "mozilla/ServoComputedData.h"
 #include "mozilla/ServoTypes.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/gfx/Types.h"
 #include "nsCSSPropertyID.h"
 #include "nsStyleAutoArray.h"
 #include "nsTArray.h"
 
-struct RawServoAnimationValueMap;
+// Forward declarations.
 
 #define SERVO_BOXED_TYPE(name_, type_) struct type_;
 #include "mozilla/ServoBoxedTypeList.h"
 #undef SERVO_BOXED_TYPE
 
 #define SERVO_ARC_TYPE(name_, type_) struct type_;
 #include "mozilla/ServoArcTypeList.h"
 #undef SERVO_ARC_TYPE
 
-namespace mozilla {
-class ServoElementSnapshot;
-class ComputedStyle;
-struct StyleAnimation;
-struct URLExtraData;
-namespace dom {
-class Element;
-class StyleChildrenIterator;
-} // namespace dom
-struct AnimationPropertySegment;
-struct ComputedTiming;
-struct Keyframe;
-struct PropertyValuePair;
-struct PropertyStyleAnimationValuePair;
-using ComputedKeyframeValues = nsTArray<PropertyStyleAnimationValuePair>;
-} // namespace mozilla
-
 class nsCSSPropertyIDSet;
 class nsCSSValue;
-struct nsFontFaceRuleContainer;
 class nsIDocument;
 class nsINode;
 class nsPresContext;
+class nsXBLBinding;
+struct nsFontFaceRuleContainer;
 struct nsTimingFunction;
-class nsXBLBinding;
-
-using mozilla::dom::StyleChildrenIterator;
-using mozilla::ServoElementSnapshot;
-
-typedef void* RawServoAnimationValueTableBorrowed;
 
-typedef nsINode RawGeckoNode;
-typedef mozilla::dom::Element RawGeckoElement;
-typedef nsIDocument RawGeckoDocument;
-typedef nsPresContext RawGeckoPresContext;
-typedef nsXBLBinding RawGeckoXBLBinding;
-typedef mozilla::URLExtraData RawGeckoURLExtraData;
-typedef nsTArray<RefPtr<RawServoAnimationValue>> RawGeckoServoAnimationValueList;
-typedef nsTArray<mozilla::Keyframe> RawGeckoKeyframeList;
-typedef nsTArray<mozilla::PropertyValuePair> RawGeckoPropertyValuePairList;
-typedef nsTArray<mozilla::ComputedKeyframeValues> RawGeckoComputedKeyframeValuesList;
-typedef nsStyleAutoArray<mozilla::StyleAnimation> RawGeckoStyleAnimationList;
-typedef nsTArray<nsFontFaceRuleContainer> RawGeckoFontFaceRuleList;
-typedef mozilla::AnimationPropertySegment RawGeckoAnimationPropertySegment;
-typedef mozilla::ComputedTiming RawGeckoComputedTiming;
-typedef nsTArray<const RawServoStyleRule*> RawGeckoServoStyleRuleList;
-typedef nsTArray<nsCSSPropertyID> RawGeckoCSSPropertyIDList;
-typedef mozilla::gfx::Float RawGeckoGfxMatrix4x4[16];
-typedef mozilla::dom::StyleChildrenIterator RawGeckoStyleChildrenIterator;
+namespace mozilla {
+class ComputedStyle;
+class ServoElementSnapshot;
+struct AnimationPropertySegment;
+struct ComputedTiming;
+struct Keyframe;
+struct PropertyStyleAnimationValuePair;
+struct PropertyValuePair;
+struct StyleAnimation;
+struct URLExtraData;
+using ComputedKeyframeValues = nsTArray<PropertyStyleAnimationValuePair>;
+using GfxMatrix4x4 = mozilla::gfx::Float[16];
 
-// We have these helper types so that we can directly generate
-// things like &T or Borrowed<T> on the Rust side in the function, providing
-// additional safety benefits.
-//
-// FFI has a problem with templated types, so we just use raw pointers here.
-//
-// The "Borrowed" types generate &T or Borrowed<T> in the nullable case.
-//
-// The "Owned" types generate Owned<T> or OwnedOrNull<T>. Some of these
-// are Servo-managed and can be converted to Box<ServoType> on the
-// Servo side.
-//
-// The "Arc" types are Servo-managed Arc<ServoType>s, which are passed
-// over FFI as Strong<T> (which is nullable).
-// Note that T != ServoType, rather T is ArcInner<ServoType>
+namespace dom {
+class StyleChildrenIterator;
+class Element;
+} // namespace dom
+} // namespace mozilla
+
 #define DECL_BORROWED_REF_TYPE_FOR(type_) typedef type_ const* type_##Borrowed;
 #define DECL_NULLABLE_BORROWED_REF_TYPE_FOR(type_) typedef type_ const* type_##BorrowedOrNull;
 #define DECL_BORROWED_MUT_REF_TYPE_FOR(type_) typedef type_* type_##BorrowedMut;
 #define DECL_NULLABLE_BORROWED_MUT_REF_TYPE_FOR(type_) typedef type_* type_##BorrowedMutOrNull;
 
-#define SERVO_ARC_TYPE(name_, type_)         \
-  DECL_NULLABLE_BORROWED_REF_TYPE_FOR(type_) \
-  DECL_BORROWED_REF_TYPE_FOR(type_)          \
-  DECL_BORROWED_MUT_REF_TYPE_FOR(type_)      \
-  struct MOZ_MUST_USE_TYPE type_##Strong     \
-  {                                          \
-    type_* mPtr;                             \
-    already_AddRefed<type_> Consume();       \
-  };
-#include "mozilla/ServoArcTypeList.h"
-#undef SERVO_ARC_TYPE
-
-// TODO(heycam): Handle these elsewhere.
-DECL_NULLABLE_BORROWED_REF_TYPE_FOR(RawServoAnimationValueMap)
-DECL_BORROWED_REF_TYPE_FOR(RawServoAnimationValueMap)
-DECL_BORROWED_MUT_REF_TYPE_FOR(RawServoAnimationValueMap)
-
-typedef mozilla::ComputedStyle const* ComputedStyleBorrowed;
-typedef mozilla::ComputedStyle const* ComputedStyleBorrowedOrNull;
-typedef ServoComputedData const* ServoComputedDataBorrowed;
-
-struct MOZ_MUST_USE_TYPE ComputedStyleStrong
-{
-  mozilla::ComputedStyle* mPtr;
-  already_AddRefed<mozilla::ComputedStyle> Consume();
-};
-
 #define DECL_OWNED_REF_TYPE_FOR(type_)    \
   typedef type_* type_##Owned;            \
   DECL_BORROWED_REF_TYPE_FOR(type_)       \
   DECL_BORROWED_MUT_REF_TYPE_FOR(type_)
 
 #define DECL_NULLABLE_OWNED_REF_TYPE_FOR(type_)    \
   typedef type_* type_##OwnedOrNull;               \
   DECL_NULLABLE_BORROWED_REF_TYPE_FOR(type_)       \
   DECL_NULLABLE_BORROWED_MUT_REF_TYPE_FOR(type_)
 
-#define SERVO_BOXED_TYPE(name_, type_)    \
-  DECL_OWNED_REF_TYPE_FOR(type_)          \
-  DECL_NULLABLE_OWNED_REF_TYPE_FOR(type_)
-#include "mozilla/ServoBoxedTypeList.h"
-#undef SERVO_BOXED_TYPE
-
-// This is a reference to a reference of RawServoDeclarationBlock, which
-// corresponds to Option<&Arc<Locked<RawServoDeclarationBlock>>> in Servo side.
-DECL_NULLABLE_BORROWED_REF_TYPE_FOR(RawServoDeclarationBlockStrong)
-DECL_NULLABLE_OWNED_REF_TYPE_FOR(StyleChildrenIterator)
-DECL_OWNED_REF_TYPE_FOR(StyleChildrenIterator)
-DECL_OWNED_REF_TYPE_FOR(ServoElementSnapshot)
-
-// We don't use BorrowedMut because the nodes may alias
-// Servo itself doesn't directly read or mutate these;
-// it only asks Gecko to do so. In case we wish to in
-// the future, we should ensure that things being mutated
-// are protected from noalias violations by a cell type
-DECL_BORROWED_REF_TYPE_FOR(RawGeckoNode)
-DECL_NULLABLE_BORROWED_REF_TYPE_FOR(RawGeckoNode)
-DECL_BORROWED_REF_TYPE_FOR(RawGeckoElement)
-DECL_NULLABLE_BORROWED_REF_TYPE_FOR(RawGeckoElement)
-DECL_BORROWED_REF_TYPE_FOR(RawGeckoDocument)
-DECL_NULLABLE_BORROWED_REF_TYPE_FOR(RawGeckoDocument)
-DECL_BORROWED_REF_TYPE_FOR(RawGeckoXBLBinding)
-DECL_NULLABLE_BORROWED_REF_TYPE_FOR(RawGeckoXBLBinding)
-DECL_BORROWED_MUT_REF_TYPE_FOR(StyleChildrenIterator)
-DECL_BORROWED_MUT_REF_TYPE_FOR(ServoElementSnapshot)
-DECL_BORROWED_REF_TYPE_FOR(nsCSSValue)
-DECL_BORROWED_MUT_REF_TYPE_FOR(nsCSSValue)
-DECL_OWNED_REF_TYPE_FOR(RawGeckoPresContext)
-DECL_BORROWED_REF_TYPE_FOR(RawGeckoPresContext)
-DECL_BORROWED_MUT_REF_TYPE_FOR(RawGeckoServoAnimationValueList)
-DECL_BORROWED_REF_TYPE_FOR(RawGeckoServoAnimationValueList)
-DECL_BORROWED_MUT_REF_TYPE_FOR(RawGeckoKeyframeList)
-DECL_BORROWED_REF_TYPE_FOR(RawGeckoKeyframeList)
-DECL_BORROWED_MUT_REF_TYPE_FOR(RawGeckoPropertyValuePairList)
-DECL_BORROWED_REF_TYPE_FOR(RawGeckoPropertyValuePairList)
-DECL_BORROWED_MUT_REF_TYPE_FOR(RawGeckoComputedKeyframeValuesList)
-DECL_BORROWED_MUT_REF_TYPE_FOR(RawGeckoStyleAnimationList)
-DECL_BORROWED_REF_TYPE_FOR(RawGeckoStyleAnimationList)
-DECL_BORROWED_MUT_REF_TYPE_FOR(nsTimingFunction)
-DECL_BORROWED_REF_TYPE_FOR(nsTimingFunction)
-DECL_BORROWED_MUT_REF_TYPE_FOR(RawGeckoFontFaceRuleList)
-DECL_BORROWED_REF_TYPE_FOR(RawGeckoAnimationPropertySegment)
-DECL_BORROWED_REF_TYPE_FOR(RawGeckoComputedTiming)
-DECL_BORROWED_MUT_REF_TYPE_FOR(RawGeckoServoStyleRuleList)
-DECL_BORROWED_MUT_REF_TYPE_FOR(nsCSSPropertyIDSet)
-DECL_BORROWED_REF_TYPE_FOR(RawGeckoCSSPropertyIDList)
-DECL_BORROWED_REF_TYPE_FOR(nsXBLBinding)
-DECL_BORROWED_MUT_REF_TYPE_FOR(RawGeckoStyleChildrenIterator)
-
-#undef DECL_ARC_REF_TYPE_FOR
-#undef DECL_OWNED_REF_TYPE_FOR
-#undef DECL_NULLABLE_OWNED_REF_TYPE_FOR
-#undef DECL_BORROWED_REF_TYPE_FOR
-#undef DECL_NULLABLE_BORROWED_REF_TYPE_FOR
-#undef DECL_BORROWED_MUT_REF_TYPE_FOR
-#undef DECL_NULLABLE_BORROWED_MUT_REF_TYPE_FOR
+#define GECKO_BORROWED_TYPE(geckotype_, ffitype_)      \
+  using ffitype_ = geckotype_;                         \
+  using ffitype_##Borrowed = const ffitype_*;          \
+  using ffitype_##BorrowedOrNull = const ffitype_*;
+#define GECKO_BORROWED_TYPE_MUT(geckotype_, ffitype_)  \
+  GECKO_BORROWED_TYPE(geckotype_, ffitype_)            \
+  using ffitype_##BorrowedMut = ffitype_*;             \
+  using ffitype_##BorrowedMutOrNull = ffitype_*;
+#include "mozilla/BorrowedTypeList.h"
+#undef GECKO_BORROWED_TYPE_MUT
+#undef GECKO_BORROWED_TYPE
 
 #define SERVO_ARC_TYPE(name_, type_)                 \
+  DECL_NULLABLE_BORROWED_REF_TYPE_FOR(type_)         \
+  DECL_BORROWED_REF_TYPE_FOR(type_)                  \
+  DECL_BORROWED_MUT_REF_TYPE_FOR(type_)              \
+  struct MOZ_MUST_USE_TYPE type_##Strong             \
+  {                                                  \
+    type_* mPtr;                                     \
+    already_AddRefed<type_> Consume();               \
+  };                                                 \
   extern "C" {                                       \
   void Servo_##name_##_AddRef(type_##Borrowed ptr);  \
   void Servo_##name_##_Release(type_##Borrowed ptr); \
   }                                                  \
   namespace mozilla {                                \
   template<> struct RefPtrTraits<type_> {            \
     static void AddRef(type_* aPtr) {                \
       Servo_##name_##_AddRef(aPtr);                  \
@@ -347,16 +243,18 @@ DECL_BORROWED_MUT_REF_TYPE_FOR(RawGeckoS
       Servo_##name_##_Release(aPtr);                 \
     }                                                \
   };                                                 \
   }
 #include "mozilla/ServoArcTypeList.h"
 #undef SERVO_ARC_TYPE
 
 #define SERVO_BOXED_TYPE(name_, type_)                      \
+  DECL_OWNED_REF_TYPE_FOR(type_)                            \
+  DECL_NULLABLE_OWNED_REF_TYPE_FOR(type_)                   \
   extern "C" void Servo_##name_##_Drop(type_##Owned ptr);   \
   namespace mozilla {                                       \
   template<>                                                \
   class DefaultDelete<type_>                                \
   {                                                         \
   public:                                                   \
     void operator()(type_* aPtr) const                      \
     {                                                       \
@@ -371,9 +269,42 @@ DECL_BORROWED_MUT_REF_TYPE_FOR(RawGeckoS
   struct nsTArrayBorrowed_##type_ {                                 \
     nsTArray<type_>* mArray;                                        \
     MOZ_IMPLICIT nsTArrayBorrowed_##type_(nsTArray<type_>* aArray)  \
       : mArray(aArray) {}                                           \
   }
 DEFINE_ARRAY_TYPE_FOR(uintptr_t);
 #undef DEFINE_ARRAY_TYPE_FOR
 
+
+// Other special cases.
+
+typedef void* RawServoAnimationValueTableBorrowed;
+
+// TODO(heycam): Handle these elsewhere.
+struct RawServoAnimationValueMap;
+DECL_NULLABLE_BORROWED_REF_TYPE_FOR(RawServoAnimationValueMap)
+DECL_BORROWED_REF_TYPE_FOR(RawServoAnimationValueMap)
+DECL_BORROWED_MUT_REF_TYPE_FOR(RawServoAnimationValueMap)
+
+typedef mozilla::ComputedStyle const* ComputedStyleBorrowed;
+typedef mozilla::ComputedStyle const* ComputedStyleBorrowedOrNull;
+typedef ServoComputedData const* ServoComputedDataBorrowed;
+
+struct MOZ_MUST_USE_TYPE ComputedStyleStrong
+{
+  mozilla::ComputedStyle* mPtr;
+  already_AddRefed<mozilla::ComputedStyle> Consume();
+};
+
+// This is a reference to a reference of RawServoDeclarationBlock, which
+// corresponds to Option<&Arc<Locked<RawServoDeclarationBlock>>> in Servo side.
+DECL_NULLABLE_BORROWED_REF_TYPE_FOR(RawServoDeclarationBlockStrong)
+
+#undef DECL_ARC_REF_TYPE_FOR
+#undef DECL_OWNED_REF_TYPE_FOR
+#undef DECL_NULLABLE_OWNED_REF_TYPE_FOR
+#undef DECL_BORROWED_REF_TYPE_FOR
+#undef DECL_NULLABLE_BORROWED_REF_TYPE_FOR
+#undef DECL_BORROWED_MUT_REF_TYPE_FOR
+#undef DECL_NULLABLE_BORROWED_MUT_REF_TYPE_FOR
+
 #endif // mozilla_ServoBindingTypes_h
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -134,22 +134,17 @@ void Servo_StyleSheet_GetSourceURL(
   RawServoStyleSheetContentsBorrowed sheet,
   nsAString* result);
 
 // We'd like to return `OriginFlags` here, but bindgen bitfield enums don't
 // work as return values with the Linux 32-bit ABI at the moment because
 // they wrap the value in a struct.
 uint8_t Servo_StyleSheet_GetOrigin(RawServoStyleSheetContentsBorrowed sheet);
 
-// TODO(heycam): RawGeckoPresContextOwned feels like the wrong type to use here
-// to indicate what we're doing. nsPresContext is a refcounted type, but we hold
-// a weak reference to it in the style set we create. Using
-// RawGeckoPresContextOwned makes it seem like we are passing ownership to
-// Servo_StyleSet_Init, which is not true.
-RawServoStyleSet* Servo_StyleSet_Init(RawGeckoPresContextOwned pres_context);
+RawServoStyleSet* Servo_StyleSet_Init(RawGeckoPresContextBorrowed pres_context);
 void Servo_StyleSet_RebuildCachedData(RawServoStyleSetBorrowed set);
 
 // We'd like to return `OriginFlags` here, but bindgen bitfield enums don't
 // work as return values with the Linux 32-bit ABI at the moment because
 // they wrap the value in a struct.
 mozilla::MediumFeaturesChangedResult Servo_StyleSet_MediumFeaturesChanged(
   RawServoStyleSetBorrowed document_set,
   nsTArray<RawServoAuthorStylesBorrowedMut>* non_document_sets,
--- a/layout/style/ServoBindings.toml
+++ b/layout/style/ServoBindings.toml
@@ -531,17 +531,16 @@ structs-types = [
     "RawServoAnimationValue",
     "RawServoFontFaceRule",
     "RawGeckoServoAnimationValueList",
     "RawServoMediaList",
     "RawServoStyleSheetContents",
     "RawServoDeclarationBlock",
     "RawServoStyleRule",
     "RawGeckoPresContext",
-    "RawGeckoPresContextOwned",
     "RawGeckoStyleAnimationList",
     "RawGeckoStyleChildrenIterator",
     "RawGeckoServoStyleRuleList",
     "RawGeckoURLExtraData",
     "RawGeckoXBLBinding",
     "RawServoSelectorList",
     "RawServoSourceSizeList",
     "RefPtr",
@@ -652,38 +651,19 @@ structs-types = [
     "FontFamilyName",
     "mozilla::SharedFontList",
     "RawServoAnimationValueMap",
 ]
 array-types = [
     { cpp-type = "uintptr_t", rust-type = "usize" },
 ]
 servo-immutable-borrow-types = [
-    "RawGeckoNode",
-    "RawGeckoElement",
-    "RawGeckoDocument",
     "RawServoDeclarationBlockStrong",
-    "RawGeckoPresContext",
-    "RawGeckoXBLBinding",
 ]
 servo-borrow-types = [
-    "nsCSSPropertyIDSet",
-    "nsCSSValue",
-    "nsTimingFunction",
-    "RawGeckoAnimationPropertySegment",
-    "RawGeckoComputedTiming",
-    "RawGeckoCSSPropertyIDList",
-    "RawGeckoKeyframeList",
-    "RawGeckoPropertyValuePairList",
-    "RawGeckoComputedKeyframeValuesList",
-    "RawGeckoFontFaceRuleList",
-    "RawGeckoServoStyleRuleList",
-    "RawGeckoServoAnimationValueList",
-    "RawGeckoStyleAnimationList",
-    "RawGeckoStyleChildrenIterator",
-    "RawServoAnimationValueMap",
+    "RawServoAnimationValueMap",  # FIXME(heycam): Try to get rid of this.
 ]
 fixups = [
     # Remap the templated string type to the helper type
     { pat = "\\bnsTString\\s*<\\s*u16\\s*>", rep = "nsString" },
     # hack for gecko-owned string
     { pat = "<\\s*nsString\\s*", rep = "<nsStringRepr" },
 ]
--- a/layout/style/StyleSheetInfo.h
+++ b/layout/style/StyleSheetInfo.h
@@ -13,16 +13,17 @@
 #include "mozilla/CORSMode.h"
 
 #include "nsIURI.h"
 
 class nsIPrincipal;
 
 namespace mozilla {
 class StyleSheet;
+struct URLExtraData;
 
 /**
  * Struct for data common to CSSStyleSheetInner and ServoStyleSheet.
  */
 struct StyleSheetInfo final
 {
   typedef net::ReferrerPolicy ReferrerPolicy;
 
--- a/layout/style/moz.build
+++ b/layout/style/moz.build
@@ -70,16 +70,17 @@ EXPORTS += [
     'nsStyleUtil.h',
     'nsTimingFunction.h',
 ]
 
 EXPORTS.mozilla += [
     '!ServoCSSPropList.h',
     'AnimationCollection.h',
     'BindingStyleRule.h',
+    'BorrowedTypeList.h',
     'CachedInheritingStyles.h',
     'ComputedStyle.h',
     'ComputedStyleInlines.h',
     'CSSEnabledState.h',
     'CSSPropFlags.h',
     'DeclarationBlock.h',
     'DocumentStyleRootIterator.h',
     'GeckoBindings.h',
--- a/servo/components/style/build_gecko.rs
+++ b/servo/components/style/build_gecko.rs
@@ -295,56 +295,71 @@ mod bindings {
         }
         let bytes = result.into_bytes();
         File::create(&out_file)
             .unwrap()
             .write_all(&bytes)
             .expect("Unable to write output");
     }
 
-    fn get_types(filename: &str, macro_name: &str) -> Vec<String> {
+    fn get_types(filename: &str, macro_pat: &str) -> Vec<(String, String)> {
         // Read the file
         let path = DISTDIR_PATH.join("include/mozilla/").join(filename);
         let mut list_file = File::open(path)
             .expect(&format!("Unable to open {}", filename));
         let mut content = String::new();
         list_file
             .read_to_string(&mut content)
             .expect(&format!("Failed to read {}", filename));
         // Remove comments
         let block_comment_re = Regex::new(r#"(?s)/\*.*?\*/"#).unwrap();
         let line_comment_re = Regex::new(r#"//.*"#).unwrap();
         let content = block_comment_re.replace_all(&content, "");
         let content = line_comment_re.replace_all(&content, "");
         // Extract the list
-        let re_string = format!(r#"^{}\(\w+,\s*(\w+)\)$"#, macro_name);
+        let re_string = format!(r#"^({})\(.+,\s*(\w+)\)$"#, macro_pat);
         let re = Regex::new(&re_string).unwrap();
         content
             .lines()
             .map(|line| line.trim())
             .filter(|line| !line.is_empty())
             .map(|line| {
-                re.captures(&line)
+                let captures = re.captures(&line)
                     .expect(&format!(
                         "Unrecognized line in {}: '{}'",
                         filename,
                         line
-                    )).get(1)
-                    .unwrap()
-                    .as_str()
-                    .to_string()
+                    ));
+                let macro_name = captures.get(1).unwrap().as_str().to_string();
+                let type_name = captures.get(2).unwrap().as_str().to_string();
+                (macro_name, type_name)
             }).collect()
     }
 
+    fn get_borrowed_types() -> Vec<(bool, String)> {
+        get_types("BorrowedTypeList.h", "GECKO_BORROWED_TYPE(?:_MUT)?")
+            .into_iter()
+            .map(|(macro_name, type_name)| {
+                (macro_name.ends_with("MUT"), type_name)
+            })
+            .collect()
+    }
+
     fn get_arc_types() -> Vec<String> {
         get_types("ServoArcTypeList.h", "SERVO_ARC_TYPE")
+            .into_iter()
+            .map(|(_, type_name)| type_name)
+            .collect()
     }
 
     fn get_boxed_types() -> Vec<String> {
         get_types("ServoBoxedTypeList.h", "SERVO_BOXED_TYPE")
+            .into_iter()
+            .map(|(_, type_name)| type_name)
+            .collect()
     }
 
     struct BuilderWithConfig<'a> {
         builder: Builder,
         config: &'a Table,
         used_keys: HashSet<&'static str>,
     }
     impl<'a> BuilderWithConfig<'a> {
@@ -539,16 +554,23 @@ mod bindings {
             })
             .handle_str_items("servo-immutable-borrow-types", |b, ty| b.borrowed_type(ty))
             // Right now the only immutable borrow types are ones which we import
             // from the |structs| module. As such, we don't need to create an opaque
             // type with zero_size_type. If we ever introduce immutable borrow types
             // which _do_ need to be opaque, we'll need a separate mode.
             .handle_str_items("servo-borrow-types", |b, ty| b.mutable_borrowed_type(ty))
             .get_builder();
+        for (is_mut, ty) in get_borrowed_types().iter() {
+            if *is_mut {
+                builder = builder.mutable_borrowed_type(ty);
+            } else {
+                builder = builder.borrowed_type(ty);
+            }
+        }
         for ty in get_arc_types().iter() {
             builder = builder
                 .blacklist_type(format!("{}Strong", ty))
                 .raw_line(format!(
                     "pub type {0}Strong = ::gecko_bindings::sugar::ownership::Strong<{0}>;",
                     ty
                 )).borrowed_type(ty)
                 .zero_size_type(ty, &structs_types);
--- a/servo/components/style/gecko/data.rs
+++ b/servo/components/style/gecko/data.rs
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //! Data needed to style a Gecko document.
 
 use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
 use context::QuirksMode;
 use dom::TElement;
 use gecko_bindings::bindings::{self, RawServoStyleSet};
-use gecko_bindings::structs::{RawGeckoPresContextOwned, ServoStyleSetSizes, StyleSheet as DomStyleSheet};
+use gecko_bindings::structs::{RawGeckoPresContextBorrowed, ServoStyleSetSizes, StyleSheet as DomStyleSheet};
 use gecko_bindings::structs::{StyleSheetInfo, nsIDocument};
 use gecko_bindings::sugar::ownership::{HasArcFFI, HasBoxFFI, HasFFI, HasSimpleFFI};
 use invalidation::media_queries::{MediaListKey, ToMediaListKey};
 use malloc_size_of::MallocSizeOfOps;
 use media_queries::{Device, MediaList};
 use properties::ComputedValues;
 use selector_parser::SnapshotMap;
 use servo_arc::Arc;
@@ -138,17 +138,17 @@ pub struct PerDocumentStyleDataImpl {
 }
 
 /// The data itself is an `AtomicRefCell`, which guarantees the proper semantics
 /// and unexpected races while trying to mutate it.
 pub struct PerDocumentStyleData(AtomicRefCell<PerDocumentStyleDataImpl>);
 
 impl PerDocumentStyleData {
     /// Create a dummy `PerDocumentStyleData`.
-    pub fn new(pres_context: RawGeckoPresContextOwned) -> Self {
+    pub fn new(pres_context: RawGeckoPresContextBorrowed) -> Self {
         let device = Device::new(pres_context);
 
         // FIXME(emilio, tlin): How is this supposed to work with XBL? This is
         // right now not always honored, see bug 1405543...
         //
         // Should we just force XBL Stylists to be NoQuirks?
         let quirks_mode =
             unsafe { (*device.pres_context().mDocument.raw::<nsIDocument>()).mCompatMode };
--- a/servo/components/style/gecko/media_queries.rs
+++ b/servo/components/style/gecko/media_queries.rs
@@ -7,17 +7,17 @@
 use app_units::AU_PER_PX;
 use app_units::Au;
 use cssparser::RGBA;
 use euclid::Size2D;
 use euclid::TypedScale;
 use gecko::values::{convert_nscolor_to_rgba, convert_rgba_to_nscolor};
 use gecko_bindings::bindings;
 use gecko_bindings::structs;
-use gecko_bindings::structs::{nsPresContext, RawGeckoPresContextOwned};
+use gecko_bindings::structs::{nsPresContext, RawGeckoPresContextBorrowed};
 use media_queries::MediaType;
 use properties::ComputedValues;
 use servo_arc::Arc;
 use std::fmt;
 use std::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize, Ordering};
 use string_cache::Atom;
 use style_traits::{CSSPixel, DevicePixel};
 use style_traits::viewport::ViewportConstraints;
@@ -25,17 +25,17 @@ use values::{CustomIdent, KeyframesName}
 use values::computed::font::FontSize;
 
 /// The `Device` in Gecko wraps a pres context, has a default values computed,
 /// and contains all the viewport rule state.
 pub struct Device {
     /// NB: The pres context lifetime is tied to the styleset, who owns the
     /// stylist, and thus the `Device`, so having a raw pres context pointer
     /// here is fine.
-    pres_context: RawGeckoPresContextOwned,
+    pres_context: RawGeckoPresContextBorrowed,
     default_values: Arc<ComputedValues>,
     /// The font size of the root element
     /// This is set when computing the style of the root
     /// element, and used for rem units in other elements.
     ///
     /// When computing the style of the root element, there can't be any
     /// other style being computed at the same time, given we need the style of
     /// the parent to compute everything else. So it is correct to just use
@@ -72,17 +72,17 @@ impl fmt::Debug for Device {
     }
 }
 
 unsafe impl Sync for Device {}
 unsafe impl Send for Device {}
 
 impl Device {
     /// Trivially constructs a new `Device`.
-    pub fn new(pres_context: RawGeckoPresContextOwned) -> Self {
+    pub fn new(pres_context: RawGeckoPresContextBorrowed) -> Self {
         assert!(!pres_context.is_null());
         Device {
             pres_context,
             default_values: ComputedValues::default_values(unsafe { &*pres_context }),
             // FIXME(bz): Seems dubious?
             root_font_size: AtomicIsize::new(FontSize::medium().size().0 as isize),
             body_text_color: AtomicUsize::new(unsafe { &*pres_context }.mDefaultColor as usize),
             used_root_font_size: AtomicBool::new(false),
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -97,17 +97,17 @@ use style::gecko_bindings::structs::{nsR
 use style::gecko_bindings::structs::AtomArray;
 use style::gecko_bindings::structs::IterationCompositeOperation;
 use style::gecko_bindings::structs::MallocSizeOf as GeckoMallocSizeOf;
 use style::gecko_bindings::structs::OriginFlags;
 use style::gecko_bindings::structs::OriginFlags_Author;
 use style::gecko_bindings::structs::OriginFlags_User;
 use style::gecko_bindings::structs::OriginFlags_UserAgent;
 use style::gecko_bindings::structs::RawGeckoGfxMatrix4x4;
-use style::gecko_bindings::structs::RawGeckoPresContextOwned;
+use style::gecko_bindings::structs::RawGeckoPresContextBorrowed;
 use style::gecko_bindings::structs::RawServoFontFaceRule;
 use style::gecko_bindings::structs::RawServoSelectorList;
 use style::gecko_bindings::structs::RawServoSourceSizeList;
 use style::gecko_bindings::structs::SeenPtrs;
 use style::gecko_bindings::structs::ServoElementSnapshotTable;
 use style::gecko_bindings::structs::ServoStyleSetSizes;
 use style::gecko_bindings::structs::ServoTraversalFlags;
 use style::gecko_bindings::structs::StyleRuleInclusion;
@@ -3350,17 +3350,17 @@ pub extern "C" fn Servo_ComputedValues_G
     }
 }
 
 /// See the comment in `Device` to see why it's ok to pass an owned reference to
 /// the pres context (hint: the context outlives the StyleSet, that holds the
 /// device alive).
 #[no_mangle]
 pub extern "C" fn Servo_StyleSet_Init(
-    pres_context: RawGeckoPresContextOwned,
+    pres_context: RawGeckoPresContextBorrowed,
 ) -> *mut RawServoStyleSet {
     let data = Box::new(PerDocumentStyleData::new(pres_context));
     Box::into_raw(data) as *mut RawServoStyleSet
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_StyleSet_RebuildCachedData(raw_data: RawServoStyleSetBorrowed) {
     let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();