Bug 1367904 - Part 4: stylo: Replace real ComputedValues with bindgenned ComputedValues2; r?bholley draft
authorManish Goregaokar <manishearth@gmail.com>
Mon, 17 Jul 2017 11:41:41 -0700
changeset 610213 000f1e7a3ebf82a3071bd535f3ad877a6b75a049
parent 610212 70324242483b654a971e6dc4c229754857d3dad4
child 610214 e275d55a9b6690bd3b9cabdb2d134d7386bda835
push id68805
push userbmo:manishearth@gmail.com
push dateTue, 18 Jul 2017 00:30:54 +0000
reviewersbholley
bugs1367904
milestone56.0a1
Bug 1367904 - Part 4: stylo: Replace real ComputedValues with bindgenned ComputedValues2; r?bholley MozReview-Commit-ID: GRkycXueUVr
layout/style/ServoBindings.h
layout/style/ServoBindings.toml
layout/style/ServoTypes.h
layout/style/generate-stylestructlist.py
servo/components/servo_arc/lib.rs
servo/components/style/gecko/generated/structs_debug.rs
servo/components/style/gecko/generated/structs_release.rs
servo/components/style/properties/gecko.mako.rs
servo/components/style/properties/properties.mako.rs
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -62,16 +62,22 @@ struct nsMediaFeature;
 struct nsStyleList;
 struct nsStyleImage;
 struct nsStyleGradientStop;
 class nsStyleGradient;
 class nsStyleCoord;
 struct nsStyleDisplay;
 class nsXBLBinding;
 
+namespace mozilla {
+  #define STYLE_STRUCT(name_, checkdata_cb_) struct Gecko##name_ {nsStyle##name_ gecko;};
+  #include "nsStyleStructList.h"
+  #undef STYLE_STRUCT
+}
+
 #define NS_DECL_THREADSAFE_FFI_REFCOUNTING(class_, name_)                     \
   void Gecko_AddRef##name_##ArbitraryThread(class_* aPtr);                    \
   void Gecko_Release##name_##ArbitraryThread(class_* aPtr);
 #define NS_IMPL_THREADSAFE_FFI_REFCOUNTING(class_, name_)                     \
   static_assert(class_::HasThreadSafeRefCnt::value,                           \
                 "NS_DECL_THREADSAFE_FFI_REFCOUNTING can only be used with "   \
                 "classes that have thread-safe refcounting");                 \
   void Gecko_AddRef##name_##ArbitraryThread(class_* aPtr)                     \
--- a/layout/style/ServoBindings.toml
+++ b/layout/style/ServoBindings.toml
@@ -309,17 +309,19 @@ opaque-types = [
 ]
 mapped-generic-types = [
     { generic = true, gecko = "mozilla::ServoUnsafeCell", servo = "::std::cell::UnsafeCell" },
     { generic = true, gecko = "mozilla::ServoCell", servo = "::std::cell::Cell" },
     { generic = false, gecko = "ServoNodeData", servo = "AtomicRefCell<ElementData>" },
     { generic = false, gecko = "mozilla::ServoWritingMode", servo = "::logical_geometry::WritingMode" },
     { generic = false, gecko = "mozilla::ServoFontComputationData", servo = "::properties::FontComputationData" },
     { generic = false, gecko = "mozilla::ServoCustomPropertiesMap", servo = "Option<::stylearc::Arc<::custom_properties::CustomPropertiesMap>>" },
+    { generic = false, gecko = "mozilla::ServoRuleNode", servo = "Option<::rule_tree::StrongRuleNode>" },
     { generic = false, gecko = "mozilla::ServoVisitedStyle", servo = "Option<::stylearc::Arc<ServoComputedValues2>>" },
+    { generic = false, gecko = "mozilla::ServoComputedValueFlags", servo = "::properties::computed_value_flags::ComputedValueFlags" },
     { generic = true, gecko = "mozilla::ServoRawOffsetArc", servo = "::stylearc::RawOffsetArc" },
 ]
 fixups = [
     { pat = "root::nsString", rep = "::nsstring::nsStringRepr" },
 ]
 
 [bindings]
 headers = ["mozilla/ServoBindings.h"]
--- a/layout/style/ServoTypes.h
+++ b/layout/style/ServoTypes.h
@@ -141,41 +141,66 @@ struct ServoFontComputationData {
   uint32_t mFour;
   uint32_t mFour2;
 };
 
 struct ServoCustomPropertiesMap {
   uintptr_t mPtr;
 };
 
+struct ServoRuleNode {
+  uintptr_t mPtr;
+};
+
 struct ServoVisitedStyle {
   uintptr_t mPtr;
 };
 
 template <typename T>
 struct ServoRawOffsetArc {
   T* mPtr;
 };
 
+struct ServoComputedValueFlags {
+  uint8_t mFlags;
+};
+
+#define STYLE_STRUCT(name_, checkdata_cb_) struct Gecko##name_;
+#define STYLE_STRUCT_LIST_IGNORE_VARIABLES
+#include "nsStyleStructList.h"
+#undef STYLE_STRUCT
+#undef STYLE_STRUCT_LIST_IGNORE_VARIABLES
+
+
 /**
  * We want C++ to be abe to read the style struct fields of ComputedValues
  * so we define this type on the C++ side and use the bindgenned version
  * on the Rust side.
  *
  * C++ just sees pointers and opaque types here, so bindgen will attempt to generate a Copy
  * impl. This will fail because the bindgenned version contains owned types. Opt out.
  *
  * <div rustbindgen nocopy></div>
  */
 struct ServoComputedValues2 {
-#define STYLE_STRUCT(name_, checkdata_cb_) ServoRawOffsetArc<nsStyle##name_> name_;
+#define STYLE_STRUCT(name_, checkdata_cb_) ServoRawOffsetArc<Gecko##name_> name_;
+  #define STYLE_STRUCT_LIST_IGNORE_VARIABLES
 #include "nsStyleStructList.h"
 #undef STYLE_STRUCT
+  #undef STYLE_STRUCT_LIST_IGNORE_VARIABLES
   ServoCustomPropertiesMap custom_properties;
   ServoWritingMode writing_mode;
   ServoFontComputationData font_computation_data;
+  /// The rule node representing the ordered list of rules matched for this
+  /// node.  Can be None for default values and text nodes.  This is
+  /// essentially an optimization to avoid referencing the root rule node.
+  ServoRuleNode rules;
+  /// The element's computed values if visited, only computed if there's a
+  /// relevant link for this element. A element's "relevant link" is the
+  /// element being matched if it is a link or the nearest ancestor link.
   ServoVisitedStyle visited_style;
+  ServoComputedValueFlags flags;
   ~ServoComputedValues2() {} // do nothing, but prevent Copy from being impl'd by bindgen
 };
 
 } // namespace mozilla
 
 #endif // mozilla_ServoTypes_h
--- a/layout/style/generate-stylestructlist.py
+++ b/layout/style/generate-stylestructlist.py
@@ -83,20 +83,24 @@ for i in range(count):
         print("Resolved items:", " ".join(resolved_items), file=sys.stderr)
         unsolved_items = [name for _, name, _, _ in STYLE_STRUCTS
                           if name not in resolved_items]
         print("There exist cyclic dependencies between " +
                   "the following structs:", " ".join(unsolved_items), file=sys.stderr)
         exit(1)
 
 def printEntry(header, i):
+    if STYLE_STRUCTS[i][1] == "Variables":
+        print("#ifndef STYLE_STRUCT_LIST_IGNORE_VARIABLES", file=header)
     print("STYLE_STRUCT_%s(%s, %s)" % STYLE_STRUCTS[i][:3], file=header)
     for dep in STYLE_STRUCTS[i][3]:
         print("STYLE_STRUCT_DEP(%s)" % (dep,), file=header)
     print("STYLE_STRUCT_END()", file=header)
+    if STYLE_STRUCTS[i][1] == "Variables":
+        print("#endif", file=header)
 
 HEADER = """/* THIS FILE IS AUTOGENERATED BY generate-stylestructlist.py - DO NOT EDIT */
 
 // IWYU pragma: private, include "nsStyleStructFwd.h"
 
 /*
  * list of structs that contain the data provided by nsStyleContext, the
  * internal API for computed style data for an element
--- a/servo/components/servo_arc/lib.rs
+++ b/servo/components/servo_arc/lib.rs
@@ -766,29 +766,49 @@ impl<T: 'static> RawOffsetArc<T> {
         // Forget the transient Arc to leave the refcount untouched.
         // XXXManishearth this can be removed when unions stabilize,
         // since then NoDrop becomes zero overhead
         mem::forget(transient);
 
         // Forward the result.
         result
     }
+
+    /// If uniquely owned, provide a mutable reference
+    /// Else create a copy, and mutate that
+    pub fn make_mut(&mut self) -> &mut T where T: Clone {
+        unsafe {
+            // extract the RawOffsetArc as an owned variable
+            let this = ptr::read(self);
+            // treat it as a real Arc
+            let mut arc = Arc::from_raw_offset(this);
+            // obtain the mutable reference. Cast away the lifetime
+            // This may mutate `arc`
+            let ret = Arc::make_mut(&mut arc) as *mut _;
+            // Store the possibly-mutated arc back inside, after converting
+            // it to a RawOffsetArc again
+            ptr::write(self, Arc::into_raw_offset(arc));
+            &mut *ret
+        }
+    }
 }
 
 impl<T: 'static> Arc<T> {
     /// Converts an Arc into a RawOffsetArc. This consumes the Arc, so the refcount
     /// is not modified.
+    #[inline]
     pub fn into_raw_offset(a: Self) -> RawOffsetArc<T> {
         RawOffsetArc {
             ptr: NonZeroPtrMut::new(Arc::into_raw(a) as *mut T),
         }
     }
 
     /// Converts a RawOffsetArc into an Arc. This consumes the RawOffsetArc, so the refcount
     /// is not modified.
+    #[inline]
     pub fn from_raw_offset(a: RawOffsetArc<T>) -> Self {
         let ptr = a.ptr.ptr();
         mem::forget(a);
         unsafe { Arc::from_raw(ptr) }
     }
 }
 
 #[cfg(test)]
--- a/servo/components/style/gecko/generated/structs_debug.rs
+++ b/servo/components/style/gecko/generated/structs_debug.rs
@@ -7,17 +7,19 @@ pub use self::root::mozilla::dom::*;
 use atomic_refcell::AtomicRefCell;
 use data::ElementData;
 pub type ServoUnsafeCell<T> = ::std::cell::UnsafeCell<T>;
 pub type ServoCell<T> = ::std::cell::Cell<T>;
 pub type ServoNodeData = AtomicRefCell<ElementData>;
 pub type ServoWritingMode = ::logical_geometry::WritingMode;
 pub type ServoFontComputationData = ::properties::FontComputationData;
 pub type ServoCustomPropertiesMap = Option<::stylearc::Arc<::custom_properties::CustomPropertiesMap>>;
+pub type ServoRuleNode = Option<::rule_tree::StrongRuleNode>;
 pub type ServoVisitedStyle = Option<::stylearc::Arc<ServoComputedValues2>>;
+pub type ServoComputedValueFlags = ::properties::computed_value_flags::ComputedValueFlags;
 pub type ServoRawOffsetArc<T> = ::stylearc::RawOffsetArc<T>;
 
 #[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
 pub mod root {
     #[repr(C)]
     pub struct __BindgenUnionField<T>(::std::marker::PhantomData<T>);
     impl <T> __BindgenUnionField<T> {
         #[inline]
@@ -7598,62 +7600,492 @@ pub mod root {
         pub type ParsingMode = u8;
         #[repr(i32)]
         #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
         pub enum InheritTarget {
             Text = 0,
             FirstLetterContinuation = 1,
             PlaceholderFrame = 2,
         }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoFont {
+            pub gecko: root::nsStyleFont,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoFont() {
+            assert_eq!(::std::mem::size_of::<GeckoFont>() , 120usize , concat
+                       ! ( "Size of: " , stringify ! ( GeckoFont ) ));
+            assert_eq! (::std::mem::align_of::<GeckoFont>() , 8usize , concat
+                        ! ( "Alignment of " , stringify ! ( GeckoFont ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoFont ) ) . gecko as * const
+                        _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoFont ) ,
+                        "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoColor {
+            pub gecko: root::nsStyleColor,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoColor() {
+            assert_eq!(::std::mem::size_of::<GeckoColor>() , 4usize , concat !
+                       ( "Size of: " , stringify ! ( GeckoColor ) ));
+            assert_eq! (::std::mem::align_of::<GeckoColor>() , 4usize , concat
+                        ! ( "Alignment of " , stringify ! ( GeckoColor ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoColor ) ) . gecko as * const
+                        _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoColor ) ,
+                        "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoList {
+            pub gecko: root::nsStyleList,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoList() {
+            assert_eq!(::std::mem::size_of::<GeckoList>() , 48usize , concat !
+                       ( "Size of: " , stringify ! ( GeckoList ) ));
+            assert_eq! (::std::mem::align_of::<GeckoList>() , 8usize , concat
+                        ! ( "Alignment of " , stringify ! ( GeckoList ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoList ) ) . gecko as * const
+                        _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoList ) ,
+                        "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoText {
+            pub gecko: root::nsStyleText,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoText() {
+            assert_eq!(::std::mem::size_of::<GeckoText>() , 160usize , concat
+                       ! ( "Size of: " , stringify ! ( GeckoText ) ));
+            assert_eq! (::std::mem::align_of::<GeckoText>() , 8usize , concat
+                        ! ( "Alignment of " , stringify ! ( GeckoText ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoText ) ) . gecko as * const
+                        _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoText ) ,
+                        "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoVisibility {
+            pub gecko: root::nsStyleVisibility,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoVisibility() {
+            assert_eq!(::std::mem::size_of::<GeckoVisibility>() , 7usize ,
+                       concat ! (
+                       "Size of: " , stringify ! ( GeckoVisibility ) ));
+            assert_eq! (::std::mem::align_of::<GeckoVisibility>() , 1usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoVisibility ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoVisibility ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoVisibility
+                        ) , "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoUserInterface {
+            pub gecko: root::nsStyleUserInterface,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoUserInterface() {
+            assert_eq!(::std::mem::size_of::<GeckoUserInterface>() , 24usize ,
+                       concat ! (
+                       "Size of: " , stringify ! ( GeckoUserInterface ) ));
+            assert_eq! (::std::mem::align_of::<GeckoUserInterface>() , 8usize
+                        , concat ! (
+                        "Alignment of " , stringify ! ( GeckoUserInterface )
+                        ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoUserInterface ) ) . gecko as
+                        * const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! (
+                        GeckoUserInterface ) , "::" , stringify ! ( gecko )
+                        ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoTableBorder {
+            pub gecko: root::nsStyleTableBorder,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoTableBorder() {
+            assert_eq!(::std::mem::size_of::<GeckoTableBorder>() , 12usize ,
+                       concat ! (
+                       "Size of: " , stringify ! ( GeckoTableBorder ) ));
+            assert_eq! (::std::mem::align_of::<GeckoTableBorder>() , 4usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoTableBorder ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoTableBorder ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! (
+                        GeckoTableBorder ) , "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoSVG {
+            pub gecko: root::nsStyleSVG,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoSVG() {
+            assert_eq!(::std::mem::size_of::<GeckoSVG>() , 128usize , concat !
+                       ( "Size of: " , stringify ! ( GeckoSVG ) ));
+            assert_eq! (::std::mem::align_of::<GeckoSVG>() , 8usize , concat !
+                        ( "Alignment of " , stringify ! ( GeckoSVG ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoSVG ) ) . gecko as * const _
+                        as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoSVG ) ,
+                        "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoBackground {
+            pub gecko: root::nsStyleBackground,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoBackground() {
+            assert_eq!(::std::mem::size_of::<GeckoBackground>() , 160usize ,
+                       concat ! (
+                       "Size of: " , stringify ! ( GeckoBackground ) ));
+            assert_eq! (::std::mem::align_of::<GeckoBackground>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoBackground ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoBackground ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoBackground
+                        ) , "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoPosition {
+            pub gecko: root::nsStylePosition,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoPosition() {
+            assert_eq!(::std::mem::size_of::<GeckoPosition>() , 520usize ,
+                       concat ! ( "Size of: " , stringify ! ( GeckoPosition )
+                       ));
+            assert_eq! (::std::mem::align_of::<GeckoPosition>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoPosition ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoPosition ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoPosition )
+                        , "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoTextReset {
+            pub gecko: root::nsStyleTextReset,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoTextReset() {
+            assert_eq!(::std::mem::size_of::<GeckoTextReset>() , 80usize ,
+                       concat ! ( "Size of: " , stringify ! ( GeckoTextReset )
+                       ));
+            assert_eq! (::std::mem::align_of::<GeckoTextReset>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoTextReset ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoTextReset ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoTextReset
+                        ) , "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoDisplay {
+            pub gecko: root::nsStyleDisplay,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoDisplay() {
+            assert_eq!(::std::mem::size_of::<GeckoDisplay>() , 416usize ,
+                       concat ! ( "Size of: " , stringify ! ( GeckoDisplay )
+                       ));
+            assert_eq! (::std::mem::align_of::<GeckoDisplay>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoDisplay ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoDisplay ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoDisplay )
+                        , "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoContent {
+            pub gecko: root::nsStyleContent,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoContent() {
+            assert_eq!(::std::mem::size_of::<GeckoContent>() , 24usize ,
+                       concat ! ( "Size of: " , stringify ! ( GeckoContent )
+                       ));
+            assert_eq! (::std::mem::align_of::<GeckoContent>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoContent ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoContent ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoContent )
+                        , "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoUIReset {
+            pub gecko: root::nsStyleUIReset,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoUIReset() {
+            assert_eq!(::std::mem::size_of::<GeckoUIReset>() , 56usize ,
+                       concat ! ( "Size of: " , stringify ! ( GeckoUIReset )
+                       ));
+            assert_eq! (::std::mem::align_of::<GeckoUIReset>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoUIReset ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoUIReset ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoUIReset )
+                        , "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoTable {
+            pub gecko: root::nsStyleTable,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoTable() {
+            assert_eq!(::std::mem::size_of::<GeckoTable>() , 8usize , concat !
+                       ( "Size of: " , stringify ! ( GeckoTable ) ));
+            assert_eq! (::std::mem::align_of::<GeckoTable>() , 4usize , concat
+                        ! ( "Alignment of " , stringify ! ( GeckoTable ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoTable ) ) . gecko as * const
+                        _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoTable ) ,
+                        "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoMargin {
+            pub gecko: root::nsStyleMargin,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoMargin() {
+            assert_eq!(::std::mem::size_of::<GeckoMargin>() , 40usize , concat
+                       ! ( "Size of: " , stringify ! ( GeckoMargin ) ));
+            assert_eq! (::std::mem::align_of::<GeckoMargin>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoMargin ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoMargin ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoMargin ) ,
+                        "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoPadding {
+            pub gecko: root::nsStylePadding,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoPadding() {
+            assert_eq!(::std::mem::size_of::<GeckoPadding>() , 40usize ,
+                       concat ! ( "Size of: " , stringify ! ( GeckoPadding )
+                       ));
+            assert_eq! (::std::mem::align_of::<GeckoPadding>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoPadding ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoPadding ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoPadding )
+                        , "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoBorder {
+            pub gecko: root::nsStyleBorder,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoBorder() {
+            assert_eq!(::std::mem::size_of::<GeckoBorder>() , 312usize ,
+                       concat ! ( "Size of: " , stringify ! ( GeckoBorder )
+                       ));
+            assert_eq! (::std::mem::align_of::<GeckoBorder>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoBorder ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoBorder ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoBorder ) ,
+                        "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoOutline {
+            pub gecko: root::nsStyleOutline,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoOutline() {
+            assert_eq!(::std::mem::size_of::<GeckoOutline>() , 104usize ,
+                       concat ! ( "Size of: " , stringify ! ( GeckoOutline )
+                       ));
+            assert_eq! (::std::mem::align_of::<GeckoOutline>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoOutline ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoOutline ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoOutline )
+                        , "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoXUL {
+            pub gecko: root::nsStyleXUL,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoXUL() {
+            assert_eq!(::std::mem::size_of::<GeckoXUL>() , 16usize , concat !
+                       ( "Size of: " , stringify ! ( GeckoXUL ) ));
+            assert_eq! (::std::mem::align_of::<GeckoXUL>() , 4usize , concat !
+                        ( "Alignment of " , stringify ! ( GeckoXUL ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoXUL ) ) . gecko as * const _
+                        as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoXUL ) ,
+                        "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoSVGReset {
+            pub gecko: root::nsStyleSVGReset,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoSVGReset() {
+            assert_eq!(::std::mem::size_of::<GeckoSVGReset>() , 192usize ,
+                       concat ! ( "Size of: " , stringify ! ( GeckoSVGReset )
+                       ));
+            assert_eq! (::std::mem::align_of::<GeckoSVGReset>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoSVGReset ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoSVGReset ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoSVGReset )
+                        , "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoColumn {
+            pub gecko: root::nsStyleColumn,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoColumn() {
+            assert_eq!(::std::mem::size_of::<GeckoColumn>() , 64usize , concat
+                       ! ( "Size of: " , stringify ! ( GeckoColumn ) ));
+            assert_eq! (::std::mem::align_of::<GeckoColumn>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoColumn ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoColumn ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoColumn ) ,
+                        "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoEffects {
+            pub gecko: root::nsStyleEffects,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoEffects() {
+            assert_eq!(::std::mem::size_of::<GeckoEffects>() , 40usize ,
+                       concat ! ( "Size of: " , stringify ! ( GeckoEffects )
+                       ));
+            assert_eq! (::std::mem::align_of::<GeckoEffects>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoEffects ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoEffects ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoEffects )
+                        , "::" , stringify ! ( gecko ) ));
+        }
         /**
  * We want C++ to be abe to read the style struct fields of ComputedValues
  * so we define this type on the C++ side and use the bindgenned version
  * on the Rust side.
  *
  * C++ just sees pointers and opaque types here, so bindgen will attempt to generate a Copy
  * impl. This will fail because the bindgenned version contains owned types. Opt out.
  *
  * <div rustbindgen nocopy></div>
  */
         #[repr(C)]
         #[derive(Debug)]
         pub struct ServoComputedValues2 {
-            pub Font: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleFont>,
-            pub Color: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleColor>,
-            pub List: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleList>,
-            pub Text: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleText>,
-            pub Visibility: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleVisibility>,
-            pub UserInterface: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleUserInterface>,
-            pub TableBorder: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleTableBorder>,
-            pub SVG: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleSVG>,
-            pub Variables: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleVariables>,
-            pub Background: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleBackground>,
-            pub Position: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStylePosition>,
-            pub TextReset: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleTextReset>,
-            pub Display: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleDisplay>,
-            pub Content: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleContent>,
-            pub UIReset: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleUIReset>,
-            pub Table: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleTable>,
-            pub Margin: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleMargin>,
-            pub Padding: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStylePadding>,
-            pub Border: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleBorder>,
-            pub Outline: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleOutline>,
-            pub XUL: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleXUL>,
-            pub SVGReset: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleSVGReset>,
-            pub Column: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleColumn>,
-            pub Effects: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleEffects>,
+            pub Font: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoFont>,
+            pub Color: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoColor>,
+            pub List: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoList>,
+            pub Text: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoText>,
+            pub Visibility: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoVisibility>,
+            pub UserInterface: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoUserInterface>,
+            pub TableBorder: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoTableBorder>,
+            pub SVG: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoSVG>,
+            pub Background: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoBackground>,
+            pub Position: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoPosition>,
+            pub TextReset: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoTextReset>,
+            pub Display: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoDisplay>,
+            pub Content: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoContent>,
+            pub UIReset: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoUIReset>,
+            pub Table: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoTable>,
+            pub Margin: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoMargin>,
+            pub Padding: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoPadding>,
+            pub Border: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoBorder>,
+            pub Outline: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoOutline>,
+            pub XUL: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoXUL>,
+            pub SVGReset: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoSVGReset>,
+            pub Column: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoColumn>,
+            pub Effects: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoEffects>,
             pub custom_properties: ::gecko_bindings::structs::ServoCustomPropertiesMap,
             pub writing_mode: ::gecko_bindings::structs::ServoWritingMode,
             pub font_computation_data: ::gecko_bindings::structs::ServoFontComputationData,
+            /// The rule node representing the ordered list of rules matched for this
+  /// node.  Can be None for default values and text nodes.  This is
+  /// essentially an optimization to avoid referencing the root rule node.
+            pub rules: ::gecko_bindings::structs::ServoRuleNode,
+            /// The element's computed values if visited, only computed if there's a
+  /// relevant link for this element. A element's "relevant link" is the
+  /// element being matched if it is a link or the nearest ancestor link.
             pub visited_style: ::gecko_bindings::structs::ServoVisitedStyle,
+            pub flags: ::gecko_bindings::structs::ServoComputedValueFlags,
         }
         #[test]
         fn bindgen_test_layout_ServoComputedValues2() {
             assert_eq!(::std::mem::size_of::<ServoComputedValues2>() ,
-                       224usize , concat ! (
+                       232usize , concat ! (
                        "Size of: " , stringify ! ( ServoComputedValues2 ) ));
             assert_eq! (::std::mem::align_of::<ServoComputedValues2>() ,
                         8usize , concat ! (
                         "Alignment of " , stringify ! ( ServoComputedValues2 )
                         ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) . Font
                         as * const _ as usize } , 0usize , concat ! (
@@ -7702,148 +8134,152 @@ pub mod root {
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) . SVG as
                         * const _ as usize } , 56usize , concat ! (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( SVG )
                         ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
-                        Variables as * const _ as usize } , 64usize , concat !
-                        (
-                        "Alignment of field: " , stringify ! (
-                        ServoComputedValues2 ) , "::" , stringify ! (
-                        Variables ) ));
-            assert_eq! (unsafe {
-                        & ( * ( 0 as * const ServoComputedValues2 ) ) .
-                        Background as * const _ as usize } , 72usize , concat
+                        Background as * const _ as usize } , 64usize , concat
                         ! (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! (
                         Background ) ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
-                        Position as * const _ as usize } , 80usize , concat !
+                        Position as * const _ as usize } , 72usize , concat !
                         (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( Position
                         ) ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
-                        TextReset as * const _ as usize } , 88usize , concat !
+                        TextReset as * const _ as usize } , 80usize , concat !
                         (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! (
                         TextReset ) ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
-                        Display as * const _ as usize } , 96usize , concat ! (
+                        Display as * const _ as usize } , 88usize , concat ! (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( Display
                         ) ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
-                        Content as * const _ as usize } , 104usize , concat !
-                        (
+                        Content as * const _ as usize } , 96usize , concat ! (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( Content
                         ) ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
-                        UIReset as * const _ as usize } , 112usize , concat !
+                        UIReset as * const _ as usize } , 104usize , concat !
                         (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( UIReset
                         ) ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) . Table
-                        as * const _ as usize } , 120usize , concat ! (
+                        as * const _ as usize } , 112usize , concat ! (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( Table )
                         ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) . Margin
-                        as * const _ as usize } , 128usize , concat ! (
+                        as * const _ as usize } , 120usize , concat ! (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( Margin )
                         ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
-                        Padding as * const _ as usize } , 136usize , concat !
+                        Padding as * const _ as usize } , 128usize , concat !
                         (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( Padding
                         ) ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) . Border
-                        as * const _ as usize } , 144usize , concat ! (
+                        as * const _ as usize } , 136usize , concat ! (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( Border )
                         ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
-                        Outline as * const _ as usize } , 152usize , concat !
+                        Outline as * const _ as usize } , 144usize , concat !
                         (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( Outline
                         ) ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) . XUL as
-                        * const _ as usize } , 160usize , concat ! (
+                        * const _ as usize } , 152usize , concat ! (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( XUL )
                         ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
-                        SVGReset as * const _ as usize } , 168usize , concat !
+                        SVGReset as * const _ as usize } , 160usize , concat !
                         (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( SVGReset
                         ) ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) . Column
-                        as * const _ as usize } , 176usize , concat ! (
+                        as * const _ as usize } , 168usize , concat ! (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( Column )
                         ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
-                        Effects as * const _ as usize } , 184usize , concat !
+                        Effects as * const _ as usize } , 176usize , concat !
                         (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( Effects
                         ) ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
-                        custom_properties as * const _ as usize } , 192usize ,
+                        custom_properties as * const _ as usize } , 184usize ,
                         concat ! (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! (
                         custom_properties ) ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
-                        writing_mode as * const _ as usize } , 200usize ,
+                        writing_mode as * const _ as usize } , 192usize ,
                         concat ! (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! (
                         writing_mode ) ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
                         font_computation_data as * const _ as usize } ,
-                        204usize , concat ! (
+                        196usize , concat ! (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! (
                         font_computation_data ) ));
             assert_eq! (unsafe {
+                        & ( * ( 0 as * const ServoComputedValues2 ) ) . rules
+                        as * const _ as usize } , 208usize , concat ! (
+                        "Alignment of field: " , stringify ! (
+                        ServoComputedValues2 ) , "::" , stringify ! ( rules )
+                        ));
+            assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
                         visited_style as * const _ as usize } , 216usize ,
                         concat ! (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! (
                         visited_style ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const ServoComputedValues2 ) ) . flags
+                        as * const _ as usize } , 224usize , concat ! (
+                        "Alignment of field: " , stringify ! (
+                        ServoComputedValues2 ) , "::" , stringify ! ( flags )
+                        ));
         }
         #[repr(u8)]
         /**
  * Enumeration that represents one of the two supported style system backends.
  */
         #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
         pub enum StyleBackendType { None = 0, Gecko = 1, Servo = 2, }
         #[repr(C)]
@@ -39044,26 +39480,26 @@ pub mod root {
                    "Size of template specialization: " , stringify ! (
                    root::nsCharTraits ) ));
         assert_eq!(::std::mem::align_of::<root::nsCharTraits>() , 1usize ,
                    concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsCharTraits ) ));
     }
     #[test]
-    fn __bindgen_test_layout__bindgen_ty_id_189482_instantiation_33() {
+    fn __bindgen_test_layout__bindgen_ty_id_189816_instantiation_33() {
         assert_eq!(::std::mem::size_of::<u8>() , 1usize , concat ! (
                    "Size of template specialization: " , stringify ! ( u8 )
                    ));
         assert_eq!(::std::mem::align_of::<u8>() , 1usize , concat ! (
                    "Alignment of template specialization: " , stringify ! ( u8
                    ) ));
     }
     #[test]
-    fn __bindgen_test_layout__bindgen_ty_id_189518_instantiation_34() {
+    fn __bindgen_test_layout__bindgen_ty_id_189852_instantiation_34() {
         assert_eq!(::std::mem::size_of::<u8>() , 1usize , concat ! (
                    "Size of template specialization: " , stringify ! ( u8 )
                    ));
         assert_eq!(::std::mem::align_of::<u8>() , 1usize , concat ! (
                    "Alignment of template specialization: " , stringify ! ( u8
                    ) ));
     }
     #[test]
--- a/servo/components/style/gecko/generated/structs_release.rs
+++ b/servo/components/style/gecko/generated/structs_release.rs
@@ -7,17 +7,19 @@ pub use self::root::mozilla::dom::*;
 use atomic_refcell::AtomicRefCell;
 use data::ElementData;
 pub type ServoUnsafeCell<T> = ::std::cell::UnsafeCell<T>;
 pub type ServoCell<T> = ::std::cell::Cell<T>;
 pub type ServoNodeData = AtomicRefCell<ElementData>;
 pub type ServoWritingMode = ::logical_geometry::WritingMode;
 pub type ServoFontComputationData = ::properties::FontComputationData;
 pub type ServoCustomPropertiesMap = Option<::stylearc::Arc<::custom_properties::CustomPropertiesMap>>;
+pub type ServoRuleNode = Option<::rule_tree::StrongRuleNode>;
 pub type ServoVisitedStyle = Option<::stylearc::Arc<ServoComputedValues2>>;
+pub type ServoComputedValueFlags = ::properties::computed_value_flags::ComputedValueFlags;
 pub type ServoRawOffsetArc<T> = ::stylearc::RawOffsetArc<T>;
 
 #[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
 pub mod root {
     #[repr(C)]
     pub struct __BindgenUnionField<T>(::std::marker::PhantomData<T>);
     impl <T> __BindgenUnionField<T> {
         #[inline]
@@ -7450,62 +7452,492 @@ pub mod root {
         pub type ParsingMode = u8;
         #[repr(i32)]
         #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
         pub enum InheritTarget {
             Text = 0,
             FirstLetterContinuation = 1,
             PlaceholderFrame = 2,
         }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoFont {
+            pub gecko: root::nsStyleFont,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoFont() {
+            assert_eq!(::std::mem::size_of::<GeckoFont>() , 120usize , concat
+                       ! ( "Size of: " , stringify ! ( GeckoFont ) ));
+            assert_eq! (::std::mem::align_of::<GeckoFont>() , 8usize , concat
+                        ! ( "Alignment of " , stringify ! ( GeckoFont ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoFont ) ) . gecko as * const
+                        _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoFont ) ,
+                        "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoColor {
+            pub gecko: root::nsStyleColor,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoColor() {
+            assert_eq!(::std::mem::size_of::<GeckoColor>() , 4usize , concat !
+                       ( "Size of: " , stringify ! ( GeckoColor ) ));
+            assert_eq! (::std::mem::align_of::<GeckoColor>() , 4usize , concat
+                        ! ( "Alignment of " , stringify ! ( GeckoColor ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoColor ) ) . gecko as * const
+                        _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoColor ) ,
+                        "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoList {
+            pub gecko: root::nsStyleList,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoList() {
+            assert_eq!(::std::mem::size_of::<GeckoList>() , 48usize , concat !
+                       ( "Size of: " , stringify ! ( GeckoList ) ));
+            assert_eq! (::std::mem::align_of::<GeckoList>() , 8usize , concat
+                        ! ( "Alignment of " , stringify ! ( GeckoList ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoList ) ) . gecko as * const
+                        _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoList ) ,
+                        "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoText {
+            pub gecko: root::nsStyleText,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoText() {
+            assert_eq!(::std::mem::size_of::<GeckoText>() , 160usize , concat
+                       ! ( "Size of: " , stringify ! ( GeckoText ) ));
+            assert_eq! (::std::mem::align_of::<GeckoText>() , 8usize , concat
+                        ! ( "Alignment of " , stringify ! ( GeckoText ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoText ) ) . gecko as * const
+                        _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoText ) ,
+                        "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoVisibility {
+            pub gecko: root::nsStyleVisibility,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoVisibility() {
+            assert_eq!(::std::mem::size_of::<GeckoVisibility>() , 7usize ,
+                       concat ! (
+                       "Size of: " , stringify ! ( GeckoVisibility ) ));
+            assert_eq! (::std::mem::align_of::<GeckoVisibility>() , 1usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoVisibility ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoVisibility ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoVisibility
+                        ) , "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoUserInterface {
+            pub gecko: root::nsStyleUserInterface,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoUserInterface() {
+            assert_eq!(::std::mem::size_of::<GeckoUserInterface>() , 24usize ,
+                       concat ! (
+                       "Size of: " , stringify ! ( GeckoUserInterface ) ));
+            assert_eq! (::std::mem::align_of::<GeckoUserInterface>() , 8usize
+                        , concat ! (
+                        "Alignment of " , stringify ! ( GeckoUserInterface )
+                        ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoUserInterface ) ) . gecko as
+                        * const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! (
+                        GeckoUserInterface ) , "::" , stringify ! ( gecko )
+                        ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoTableBorder {
+            pub gecko: root::nsStyleTableBorder,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoTableBorder() {
+            assert_eq!(::std::mem::size_of::<GeckoTableBorder>() , 12usize ,
+                       concat ! (
+                       "Size of: " , stringify ! ( GeckoTableBorder ) ));
+            assert_eq! (::std::mem::align_of::<GeckoTableBorder>() , 4usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoTableBorder ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoTableBorder ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! (
+                        GeckoTableBorder ) , "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoSVG {
+            pub gecko: root::nsStyleSVG,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoSVG() {
+            assert_eq!(::std::mem::size_of::<GeckoSVG>() , 128usize , concat !
+                       ( "Size of: " , stringify ! ( GeckoSVG ) ));
+            assert_eq! (::std::mem::align_of::<GeckoSVG>() , 8usize , concat !
+                        ( "Alignment of " , stringify ! ( GeckoSVG ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoSVG ) ) . gecko as * const _
+                        as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoSVG ) ,
+                        "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoBackground {
+            pub gecko: root::nsStyleBackground,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoBackground() {
+            assert_eq!(::std::mem::size_of::<GeckoBackground>() , 160usize ,
+                       concat ! (
+                       "Size of: " , stringify ! ( GeckoBackground ) ));
+            assert_eq! (::std::mem::align_of::<GeckoBackground>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoBackground ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoBackground ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoBackground
+                        ) , "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoPosition {
+            pub gecko: root::nsStylePosition,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoPosition() {
+            assert_eq!(::std::mem::size_of::<GeckoPosition>() , 520usize ,
+                       concat ! ( "Size of: " , stringify ! ( GeckoPosition )
+                       ));
+            assert_eq! (::std::mem::align_of::<GeckoPosition>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoPosition ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoPosition ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoPosition )
+                        , "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoTextReset {
+            pub gecko: root::nsStyleTextReset,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoTextReset() {
+            assert_eq!(::std::mem::size_of::<GeckoTextReset>() , 80usize ,
+                       concat ! ( "Size of: " , stringify ! ( GeckoTextReset )
+                       ));
+            assert_eq! (::std::mem::align_of::<GeckoTextReset>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoTextReset ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoTextReset ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoTextReset
+                        ) , "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoDisplay {
+            pub gecko: root::nsStyleDisplay,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoDisplay() {
+            assert_eq!(::std::mem::size_of::<GeckoDisplay>() , 416usize ,
+                       concat ! ( "Size of: " , stringify ! ( GeckoDisplay )
+                       ));
+            assert_eq! (::std::mem::align_of::<GeckoDisplay>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoDisplay ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoDisplay ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoDisplay )
+                        , "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoContent {
+            pub gecko: root::nsStyleContent,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoContent() {
+            assert_eq!(::std::mem::size_of::<GeckoContent>() , 24usize ,
+                       concat ! ( "Size of: " , stringify ! ( GeckoContent )
+                       ));
+            assert_eq! (::std::mem::align_of::<GeckoContent>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoContent ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoContent ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoContent )
+                        , "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoUIReset {
+            pub gecko: root::nsStyleUIReset,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoUIReset() {
+            assert_eq!(::std::mem::size_of::<GeckoUIReset>() , 56usize ,
+                       concat ! ( "Size of: " , stringify ! ( GeckoUIReset )
+                       ));
+            assert_eq! (::std::mem::align_of::<GeckoUIReset>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoUIReset ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoUIReset ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoUIReset )
+                        , "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoTable {
+            pub gecko: root::nsStyleTable,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoTable() {
+            assert_eq!(::std::mem::size_of::<GeckoTable>() , 8usize , concat !
+                       ( "Size of: " , stringify ! ( GeckoTable ) ));
+            assert_eq! (::std::mem::align_of::<GeckoTable>() , 4usize , concat
+                        ! ( "Alignment of " , stringify ! ( GeckoTable ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoTable ) ) . gecko as * const
+                        _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoTable ) ,
+                        "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoMargin {
+            pub gecko: root::nsStyleMargin,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoMargin() {
+            assert_eq!(::std::mem::size_of::<GeckoMargin>() , 40usize , concat
+                       ! ( "Size of: " , stringify ! ( GeckoMargin ) ));
+            assert_eq! (::std::mem::align_of::<GeckoMargin>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoMargin ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoMargin ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoMargin ) ,
+                        "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoPadding {
+            pub gecko: root::nsStylePadding,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoPadding() {
+            assert_eq!(::std::mem::size_of::<GeckoPadding>() , 40usize ,
+                       concat ! ( "Size of: " , stringify ! ( GeckoPadding )
+                       ));
+            assert_eq! (::std::mem::align_of::<GeckoPadding>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoPadding ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoPadding ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoPadding )
+                        , "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoBorder {
+            pub gecko: root::nsStyleBorder,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoBorder() {
+            assert_eq!(::std::mem::size_of::<GeckoBorder>() , 312usize ,
+                       concat ! ( "Size of: " , stringify ! ( GeckoBorder )
+                       ));
+            assert_eq! (::std::mem::align_of::<GeckoBorder>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoBorder ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoBorder ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoBorder ) ,
+                        "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoOutline {
+            pub gecko: root::nsStyleOutline,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoOutline() {
+            assert_eq!(::std::mem::size_of::<GeckoOutline>() , 104usize ,
+                       concat ! ( "Size of: " , stringify ! ( GeckoOutline )
+                       ));
+            assert_eq! (::std::mem::align_of::<GeckoOutline>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoOutline ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoOutline ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoOutline )
+                        , "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoXUL {
+            pub gecko: root::nsStyleXUL,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoXUL() {
+            assert_eq!(::std::mem::size_of::<GeckoXUL>() , 16usize , concat !
+                       ( "Size of: " , stringify ! ( GeckoXUL ) ));
+            assert_eq! (::std::mem::align_of::<GeckoXUL>() , 4usize , concat !
+                        ( "Alignment of " , stringify ! ( GeckoXUL ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoXUL ) ) . gecko as * const _
+                        as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoXUL ) ,
+                        "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoSVGReset {
+            pub gecko: root::nsStyleSVGReset,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoSVGReset() {
+            assert_eq!(::std::mem::size_of::<GeckoSVGReset>() , 192usize ,
+                       concat ! ( "Size of: " , stringify ! ( GeckoSVGReset )
+                       ));
+            assert_eq! (::std::mem::align_of::<GeckoSVGReset>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoSVGReset ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoSVGReset ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoSVGReset )
+                        , "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoColumn {
+            pub gecko: root::nsStyleColumn,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoColumn() {
+            assert_eq!(::std::mem::size_of::<GeckoColumn>() , 64usize , concat
+                       ! ( "Size of: " , stringify ! ( GeckoColumn ) ));
+            assert_eq! (::std::mem::align_of::<GeckoColumn>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoColumn ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoColumn ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoColumn ) ,
+                        "::" , stringify ! ( gecko ) ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct GeckoEffects {
+            pub gecko: root::nsStyleEffects,
+        }
+        #[test]
+        fn bindgen_test_layout_GeckoEffects() {
+            assert_eq!(::std::mem::size_of::<GeckoEffects>() , 40usize ,
+                       concat ! ( "Size of: " , stringify ! ( GeckoEffects )
+                       ));
+            assert_eq! (::std::mem::align_of::<GeckoEffects>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( GeckoEffects ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const GeckoEffects ) ) . gecko as *
+                        const _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( GeckoEffects )
+                        , "::" , stringify ! ( gecko ) ));
+        }
         /**
  * We want C++ to be abe to read the style struct fields of ComputedValues
  * so we define this type on the C++ side and use the bindgenned version
  * on the Rust side.
  *
  * C++ just sees pointers and opaque types here, so bindgen will attempt to generate a Copy
  * impl. This will fail because the bindgenned version contains owned types. Opt out.
  *
  * <div rustbindgen nocopy></div>
  */
         #[repr(C)]
         #[derive(Debug)]
         pub struct ServoComputedValues2 {
-            pub Font: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleFont>,
-            pub Color: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleColor>,
-            pub List: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleList>,
-            pub Text: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleText>,
-            pub Visibility: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleVisibility>,
-            pub UserInterface: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleUserInterface>,
-            pub TableBorder: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleTableBorder>,
-            pub SVG: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleSVG>,
-            pub Variables: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleVariables>,
-            pub Background: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleBackground>,
-            pub Position: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStylePosition>,
-            pub TextReset: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleTextReset>,
-            pub Display: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleDisplay>,
-            pub Content: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleContent>,
-            pub UIReset: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleUIReset>,
-            pub Table: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleTable>,
-            pub Margin: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleMargin>,
-            pub Padding: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStylePadding>,
-            pub Border: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleBorder>,
-            pub Outline: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleOutline>,
-            pub XUL: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleXUL>,
-            pub SVGReset: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleSVGReset>,
-            pub Column: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleColumn>,
-            pub Effects: ::gecko_bindings::structs::ServoRawOffsetArc<root::nsStyleEffects>,
+            pub Font: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoFont>,
+            pub Color: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoColor>,
+            pub List: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoList>,
+            pub Text: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoText>,
+            pub Visibility: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoVisibility>,
+            pub UserInterface: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoUserInterface>,
+            pub TableBorder: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoTableBorder>,
+            pub SVG: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoSVG>,
+            pub Background: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoBackground>,
+            pub Position: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoPosition>,
+            pub TextReset: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoTextReset>,
+            pub Display: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoDisplay>,
+            pub Content: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoContent>,
+            pub UIReset: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoUIReset>,
+            pub Table: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoTable>,
+            pub Margin: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoMargin>,
+            pub Padding: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoPadding>,
+            pub Border: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoBorder>,
+            pub Outline: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoOutline>,
+            pub XUL: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoXUL>,
+            pub SVGReset: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoSVGReset>,
+            pub Column: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoColumn>,
+            pub Effects: ::gecko_bindings::structs::ServoRawOffsetArc<root::mozilla::GeckoEffects>,
             pub custom_properties: ::gecko_bindings::structs::ServoCustomPropertiesMap,
             pub writing_mode: ::gecko_bindings::structs::ServoWritingMode,
             pub font_computation_data: ::gecko_bindings::structs::ServoFontComputationData,
+            /// The rule node representing the ordered list of rules matched for this
+  /// node.  Can be None for default values and text nodes.  This is
+  /// essentially an optimization to avoid referencing the root rule node.
+            pub rules: ::gecko_bindings::structs::ServoRuleNode,
+            /// The element's computed values if visited, only computed if there's a
+  /// relevant link for this element. A element's "relevant link" is the
+  /// element being matched if it is a link or the nearest ancestor link.
             pub visited_style: ::gecko_bindings::structs::ServoVisitedStyle,
+            pub flags: ::gecko_bindings::structs::ServoComputedValueFlags,
         }
         #[test]
         fn bindgen_test_layout_ServoComputedValues2() {
             assert_eq!(::std::mem::size_of::<ServoComputedValues2>() ,
-                       224usize , concat ! (
+                       232usize , concat ! (
                        "Size of: " , stringify ! ( ServoComputedValues2 ) ));
             assert_eq! (::std::mem::align_of::<ServoComputedValues2>() ,
                         8usize , concat ! (
                         "Alignment of " , stringify ! ( ServoComputedValues2 )
                         ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) . Font
                         as * const _ as usize } , 0usize , concat ! (
@@ -7554,148 +7986,152 @@ pub mod root {
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) . SVG as
                         * const _ as usize } , 56usize , concat ! (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( SVG )
                         ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
-                        Variables as * const _ as usize } , 64usize , concat !
-                        (
-                        "Alignment of field: " , stringify ! (
-                        ServoComputedValues2 ) , "::" , stringify ! (
-                        Variables ) ));
-            assert_eq! (unsafe {
-                        & ( * ( 0 as * const ServoComputedValues2 ) ) .
-                        Background as * const _ as usize } , 72usize , concat
+                        Background as * const _ as usize } , 64usize , concat
                         ! (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! (
                         Background ) ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
-                        Position as * const _ as usize } , 80usize , concat !
+                        Position as * const _ as usize } , 72usize , concat !
                         (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( Position
                         ) ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
-                        TextReset as * const _ as usize } , 88usize , concat !
+                        TextReset as * const _ as usize } , 80usize , concat !
                         (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! (
                         TextReset ) ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
-                        Display as * const _ as usize } , 96usize , concat ! (
+                        Display as * const _ as usize } , 88usize , concat ! (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( Display
                         ) ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
-                        Content as * const _ as usize } , 104usize , concat !
-                        (
+                        Content as * const _ as usize } , 96usize , concat ! (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( Content
                         ) ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
-                        UIReset as * const _ as usize } , 112usize , concat !
+                        UIReset as * const _ as usize } , 104usize , concat !
                         (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( UIReset
                         ) ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) . Table
-                        as * const _ as usize } , 120usize , concat ! (
+                        as * const _ as usize } , 112usize , concat ! (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( Table )
                         ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) . Margin
-                        as * const _ as usize } , 128usize , concat ! (
+                        as * const _ as usize } , 120usize , concat ! (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( Margin )
                         ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
-                        Padding as * const _ as usize } , 136usize , concat !
+                        Padding as * const _ as usize } , 128usize , concat !
                         (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( Padding
                         ) ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) . Border
-                        as * const _ as usize } , 144usize , concat ! (
+                        as * const _ as usize } , 136usize , concat ! (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( Border )
                         ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
-                        Outline as * const _ as usize } , 152usize , concat !
+                        Outline as * const _ as usize } , 144usize , concat !
                         (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( Outline
                         ) ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) . XUL as
-                        * const _ as usize } , 160usize , concat ! (
+                        * const _ as usize } , 152usize , concat ! (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( XUL )
                         ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
-                        SVGReset as * const _ as usize } , 168usize , concat !
+                        SVGReset as * const _ as usize } , 160usize , concat !
                         (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( SVGReset
                         ) ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) . Column
-                        as * const _ as usize } , 176usize , concat ! (
+                        as * const _ as usize } , 168usize , concat ! (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( Column )
                         ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
-                        Effects as * const _ as usize } , 184usize , concat !
+                        Effects as * const _ as usize } , 176usize , concat !
                         (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! ( Effects
                         ) ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
-                        custom_properties as * const _ as usize } , 192usize ,
+                        custom_properties as * const _ as usize } , 184usize ,
                         concat ! (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! (
                         custom_properties ) ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
-                        writing_mode as * const _ as usize } , 200usize ,
+                        writing_mode as * const _ as usize } , 192usize ,
                         concat ! (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! (
                         writing_mode ) ));
             assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
                         font_computation_data as * const _ as usize } ,
-                        204usize , concat ! (
+                        196usize , concat ! (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! (
                         font_computation_data ) ));
             assert_eq! (unsafe {
+                        & ( * ( 0 as * const ServoComputedValues2 ) ) . rules
+                        as * const _ as usize } , 208usize , concat ! (
+                        "Alignment of field: " , stringify ! (
+                        ServoComputedValues2 ) , "::" , stringify ! ( rules )
+                        ));
+            assert_eq! (unsafe {
                         & ( * ( 0 as * const ServoComputedValues2 ) ) .
                         visited_style as * const _ as usize } , 216usize ,
                         concat ! (
                         "Alignment of field: " , stringify ! (
                         ServoComputedValues2 ) , "::" , stringify ! (
                         visited_style ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const ServoComputedValues2 ) ) . flags
+                        as * const _ as usize } , 224usize , concat ! (
+                        "Alignment of field: " , stringify ! (
+                        ServoComputedValues2 ) , "::" , stringify ! ( flags )
+                        ));
         }
         #[repr(u8)]
         /**
  * Enumeration that represents one of the two supported style system backends.
  */
         #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
         pub enum StyleBackendType { None = 0, Gecko = 1, Servo = 2, }
         #[repr(C)]
@@ -38408,26 +38844,26 @@ pub mod root {
                    "Size of template specialization: " , stringify ! (
                    root::nsCharTraits ) ));
         assert_eq!(::std::mem::align_of::<root::nsCharTraits>() , 1usize ,
                    concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsCharTraits ) ));
     }
     #[test]
-    fn __bindgen_test_layout__bindgen_ty_id_187141_instantiation_33() {
+    fn __bindgen_test_layout__bindgen_ty_id_187475_instantiation_33() {
         assert_eq!(::std::mem::size_of::<u8>() , 1usize , concat ! (
                    "Size of template specialization: " , stringify ! ( u8 )
                    ));
         assert_eq!(::std::mem::align_of::<u8>() , 1usize , concat ! (
                    "Alignment of template specialization: " , stringify ! ( u8
                    ) ));
     }
     #[test]
-    fn __bindgen_test_layout__bindgen_ty_id_187177_instantiation_34() {
+    fn __bindgen_test_layout__bindgen_ty_id_187511_instantiation_34() {
         assert_eq!(::std::mem::size_of::<u8>() , 1usize , concat ! (
                    "Size of template specialization: " , stringify ! ( u8 )
                    ));
         assert_eq!(::std::mem::align_of::<u8>() , 1usize , concat ! (
                    "Alignment of template specialization: " , stringify ! ( u8
                    ) ));
     }
     #[test]
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -53,52 +53,49 @@ use gecko::values::GeckoStyleCoordConver
 use gecko::values::round_border_to_device_pixels;
 use logical_geometry::WritingMode;
 use media_queries::Device;
 use properties::animated_properties::TransitionProperty;
 use properties::computed_value_flags::ComputedValueFlags;
 use properties::{longhands, FontComputationData, Importance, LonghandId};
 use properties::{PropertyDeclaration, PropertyDeclarationBlock, PropertyDeclarationId};
 use rule_tree::StrongRuleNode;
-use std::fmt::{self, Debug};
 use std::mem::{forget, transmute, zeroed};
 use std::ptr;
-use stylearc::Arc;
+use stylearc::{Arc, RawOffsetArc};
 use std::cmp;
 use values::{Auto, CustomIdent, Either, KeyframesName};
 use values::computed::ToComputedValue;
 use values::computed::effects::{BoxShadow, Filter, SimpleShadow};
 use values::specified::length::Percentage;
 use computed_values::border_style;
 
 pub mod style_structs {
     % for style_struct in data.style_structs:
     pub use super::${style_struct.gecko_struct_name} as ${style_struct.name};
     % endfor
 }
 
-// FIXME(emilio): Unify both definitions, since they're equal now.
-#[derive(Clone)]
-pub struct ComputedValues {
-    % for style_struct in data.style_structs:
-    ${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
-    % endfor
-    custom_properties: Option<Arc<CustomPropertiesMap>>,
-    pub writing_mode: WritingMode,
-    pub font_computation_data: FontComputationData,
-    pub flags: ComputedValueFlags,
-
-    /// The rule node representing the ordered list of rules matched for this
-    /// node.  Can be None for default values and text nodes.  This is
-    /// essentially an optimization to avoid referencing the root rule node.
-    pub rules: Option<StrongRuleNode>,
-    /// The element's computed values if visited, only computed if there's a
-    /// relevant link for this element. A element's "relevant link" is the
-    /// element being matched if it is a link or the nearest ancestor link.
-    visited_style: Option<Arc<ComputedValues>>,
+
+pub use ::gecko_bindings::structs::mozilla::ServoComputedValues2 as ComputedValues;
+
+impl Clone for ComputedValues {
+    fn clone(&self) -> Self {
+        ComputedValues {
+            % for style_struct in data.style_structs:
+                ${style_struct.gecko_name}: self.${style_struct.gecko_name}.clone(),
+            % endfor
+            custom_properties: self.custom_properties.clone(),
+            writing_mode: self.writing_mode.clone(),
+            font_computation_data: self.font_computation_data.clone(),
+            flags: self.flags.clone(),
+            rules: self.rules.clone(),
+            visited_style: self.visited_style.clone(),
+        }
+    }
 }
 
 impl ComputedValues {
     pub fn new(custom_properties: Option<Arc<CustomPropertiesMap>>,
                writing_mode: WritingMode,
                font_size_keyword: Option<(longhands::font_size::KeywordSize, f32)>,
                flags: ComputedValueFlags,
                rules: Option<StrongRuleNode>,
@@ -110,31 +107,31 @@ impl ComputedValues {
         ComputedValues {
             custom_properties,
             writing_mode,
             font_computation_data: FontComputationData::new(font_size_keyword),
             flags,
             rules,
             visited_style: visited_style,
             % for style_struct in data.style_structs:
-            ${style_struct.ident},
+            ${style_struct.gecko_name}: Arc::into_raw_offset(${style_struct.ident}),
             % endfor
         }
     }
 
     pub fn default_values(pres_context: RawGeckoPresContextBorrowed) -> Arc<Self> {
         Arc::new(ComputedValues {
             custom_properties: None,
             writing_mode: WritingMode::empty(), // FIXME(bz): This seems dubious
             font_computation_data: FontComputationData::default_values(),
             flags: ComputedValueFlags::empty(),
             rules: None,
             visited_style: None,
             % for style_struct in data.style_structs:
-                ${style_struct.ident}: style_structs::${style_struct.name}::default(pres_context),
+                ${style_struct.gecko_name}: Arc::into_raw_offset(style_structs::${style_struct.name}::default(pres_context)),
             % endfor
         })
     }
 
     #[inline]
     pub fn is_display_contents(&self) -> bool {
         self.get_box().clone_display() == longhands::display::computed_value::T::contents
     }
@@ -144,30 +141,31 @@ impl ComputedValues {
     #[inline]
     pub fn ineffective_content_property(&self) -> bool {
         self.get_counters().ineffective_content_property()
     }
 
     % for style_struct in data.style_structs:
     #[inline]
     pub fn clone_${style_struct.name_lower}(&self) -> Arc<style_structs::${style_struct.name}> {
-        self.${style_struct.ident}.clone()
+        Arc::from_raw_offset(self.${style_struct.gecko_name}.clone())
     }
     #[inline]
     pub fn get_${style_struct.name_lower}(&self) -> &style_structs::${style_struct.name} {
-        &self.${style_struct.ident}
-    }
-
-    pub fn ${style_struct.name_lower}_arc(&self) -> &Arc<style_structs::${style_struct.name}> {
-        &self.${style_struct.ident}
+        &self.${style_struct.gecko_name}
+    }
+
+
+    pub fn ${style_struct.name_lower}_arc(&self) -> &RawOffsetArc<style_structs::${style_struct.name}> {
+        &self.${style_struct.gecko_name}
     }
 
     #[inline]
     pub fn mutate_${style_struct.name_lower}(&mut self) -> &mut style_structs::${style_struct.name} {
-        Arc::make_mut(&mut self.${style_struct.ident})
+        RawOffsetArc::make_mut(&mut self.${style_struct.gecko_name})
     }
     % endfor
 
     /// Gets a reference to the rule node. Panic if no rule node exists.
     pub fn rules(&self) -> &StrongRuleNode {
         self.rules.as_ref().unwrap()
     }
 
@@ -233,19 +231,17 @@ impl ComputedValues {
             % endfor
             PropertyDeclarationId::Custom(_name) => unimplemented!(),
             _ => unimplemented!()
         }
     }
 }
 
 <%def name="declare_style_struct(style_struct)">
-pub struct ${style_struct.gecko_struct_name} {
-    gecko: ${style_struct.gecko_ffi_name},
-}
+pub use ::gecko_bindings::structs::mozilla::Gecko${style_struct.gecko_name} as ${style_struct.gecko_struct_name};
 impl ${style_struct.gecko_struct_name} {
     pub fn gecko(&self) -> &${style_struct.gecko_ffi_name} {
         &self.gecko
     }
     pub fn gecko_mut(&mut self) -> &mut ${style_struct.gecko_ffi_name} {
         &mut self.gecko
     }
 }
@@ -732,30 +728,16 @@ impl Clone for ${style_struct.gecko_stru
         unsafe {
             let mut result = ${style_struct.gecko_struct_name} { gecko: zeroed() };
             Gecko_CopyConstruct_${style_struct.gecko_ffi_name}(&mut result.gecko, &self.gecko);
             result
         }
     }
 }
 
-// FIXME(bholley): Make bindgen generate Debug for all types.
-%if style_struct.gecko_ffi_name in ("nsStyle" + x for x in "Border Display List Background Font SVGReset".split()):
-impl Debug for ${style_struct.gecko_struct_name} {
-    // FIXME(bholley): Generate this.
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "Gecko style struct: ${style_struct.gecko_struct_name}")
-    }
-}
-%else:
-impl Debug for ${style_struct.gecko_struct_name} {
-    // FIXME(bholley): Generate this.
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.gecko.fmt(f) }
-}
-%endif
 </%def>
 
 <%def name="impl_simple_type_with_conversion(ident, gecko_ffi_name=None)">
     <%
     if gecko_ffi_name is None:
         gecko_ffi_name = "m" + to_camel_case(ident)
     %>
 
--- a/servo/components/style/properties/properties.mako.rs
+++ b/servo/components/style/properties/properties.mako.rs
@@ -1881,17 +1881,17 @@ pub type ServoComputedValues = ComputedV
 
 /// The struct that Servo uses to represent computed values.
 ///
 /// This struct contains an immutable atomically-reference-counted pointer to
 /// every kind of style struct.
 ///
 /// When needed, the structs may be copied in order to get mutated.
 #[cfg(feature = "servo")]
-#[cfg_attr(feature = "servo", derive(Clone))]
+#[cfg_attr(feature = "servo", derive(Clone, Debug))]
 pub struct ComputedValues {
     % for style_struct in data.active_style_structs():
         ${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
     % endfor
     custom_properties: Option<Arc<::custom_properties::CustomPropertiesMap>>,
     /// The writing mode of this computed values struct.
     pub writing_mode: WritingMode,
     /// The keyword behind the current font-size property, if any
@@ -2232,24 +2232,16 @@ impl ComputedValues {
                     .and_then(|map| map.get_computed_value(name))
                     .map(|value| value.to_css_string())
                     .unwrap_or(String::new())
             }
         }
     }
 }
 
-// We manually implement Debug for ComputedValues so that we can avoid the
-// verbose stringification of every property and instead focus on a few values.
-impl fmt::Debug for ComputedValues {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "ComputedValues {{ rules: {:?}, .. }}", self.rules)
-    }
-}
-
 /// Return a WritingMode bitflags from the relevant CSS properties.
 pub fn get_writing_mode(inheritedbox_style: &style_structs::InheritedBox) -> WritingMode {
     use logical_geometry;
     let mut flags = WritingMode::empty();
     match inheritedbox_style.clone_direction() {
         computed_values::direction::T::ltr => {},
         computed_values::direction::T::rtl => {
             flags.insert(logical_geometry::FLAG_RTL);
@@ -2291,20 +2283,34 @@ pub fn get_writing_mode(inheritedbox_sty
                 flags.insert(logical_geometry::FLAG_SIDEWAYS);
             },
         }
     }
     % endif
     flags
 }
 
+% if product == "gecko":
+    pub use ::stylearc::RawOffsetArc as BuilderArc;
+    /// Clone an arc, returning a regular arc
+    fn clone_arc<T: 'static>(x: &BuilderArc<T>) -> Arc<T> {
+        Arc::from_raw_offset(x.clone())
+    }
+% else:
+    pub use ::stylearc::Arc as BuilderArc;
+    /// Clone an arc, returning a regular arc
+    fn clone_arc<T: 'static>(x: &BuilderArc<T>) -> Arc<T> {
+        x.clone()
+    }
+% endif
+
 /// A reference to a style struct of the parent, or our own style struct.
 pub enum StyleStructRef<'a, T: 'static> {
     /// A borrowed struct from the parent, for example, for inheriting style.
-    Borrowed(&'a Arc<T>),
+    Borrowed(&'a BuilderArc<T>),
     /// An owned struct, that we've already mutated.
     Owned(UniqueArc<T>),
     /// Temporarily vacated, will panic if accessed
     Vacated,
 }
 
 impl<'a, T: 'a> StyleStructRef<'a, T>
     where T: Clone,
@@ -2355,17 +2361,17 @@ impl<'a, T: 'a> StyleStructRef<'a, T>
         }
     }
 
     /// Returns an `Arc` to the internal struct, constructing one if
     /// appropriate.
     pub fn build(self) -> Arc<T> {
         match self {
             StyleStructRef::Owned(v) => v.shareable(),
-            StyleStructRef::Borrowed(v) => v.clone(),
+            StyleStructRef::Borrowed(v) => clone_arc(v),
             StyleStructRef::Vacated => panic!("Accessed vacated style struct")
         }
     }
 }
 
 impl<'a, T: 'a> Deref for StyleStructRef<'a, T> {
     type Target = T;