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 499658 8819dd315519624abe75cb340aa1ae8cfd62ca86
parent 499657 5adb545ddcfd3f1275a6ad5ea62bb2b9588a48dc
child 499659 6609c511837ddeb4a88ba6a5341b26202ebe316e
push id1864
push userffxbld-merge
push dateMon, 03 Dec 2018 15:51:40 +0000
treeherdermozilla-release@f040763d99ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs1498755
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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();