Bug 1478330: Generate StyleDisplay using cbindgen. r=heycam
authorEmilio Cobos Álvarez <emilio@crisal.io>
Wed, 25 Jul 2018 13:15:21 +0200
changeset 428604 4b1c6659a5f5a28a54de6ee00caa09265050e8a7
parent 428603 8e257791eccf389ed0ef642ce8d46af5f0d93b9f
child 428605 ced9b3994cf4316a57e1777bb3738cc350a1196d
push id34337
push userncsoregi@mozilla.com
push dateThu, 26 Jul 2018 21:58:45 +0000
treeherdermozilla-central@8f2f847b2f9d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1478330
milestone63.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1478330: Generate StyleDisplay using cbindgen. r=heycam We use the same setup WR uses, which is checking-in the files. But I think it's much better than keeping the two things in sync manually :) When you add a new value, you need to add it to the rust source, then run the command, but since it doesn't need to build the style crate (it uses the Rust AST, doesn't build) there's no problem. Differential Revision: https://phabricator.services.mozilla.com/D2354 MozReview-Commit-ID: DnXkNAzP54H
layout/style/ServoStyleConsts.h
layout/style/moz.build
layout/style/nsStyleConsts.h
servo/components/style/cbindgen.toml
servo/components/style/properties/gecko.mako.rs
servo/components/style/values/specified/box.rs
new file mode 100644
--- /dev/null
+++ b/layout/style/ServoStyleConsts.h
@@ -0,0 +1,74 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* Generated with cbindgen:0.6.1 */
+
+/* DO NOT MODIFY THIS MANUALLY! This file was generated using cbindgen.
+ * To generate this file:
+ *   1. Get the latest cbindgen using `cargo install --force cbindgen`
+ *      a. Alternatively, you can clone `https://github.com/eqrion/cbindgen` and use a tagged release
+ *   2. Run `rustup run nightly cbindgen toolkit/library/rust/ --lockfile Cargo.lock --crate style -o layout/style/ServoStyleConsts.h`
+ */
+
+#include <cstdint>
+#include <cstdlib>
+
+namespace mozilla {
+
+// Defines an element’s display type, which consists of
+// the two basic qualities of how an element generates boxes
+// <https://drafts.csswg.org/css-display/#propdef-display>
+//
+//
+// NOTE(emilio): Order is important in Gecko!
+//
+// If you change it, make sure to take a look at the
+// FrameConstructionDataByDisplay stuff (both the XUL and non-XUL version), and
+// ensure it's still correct!
+//
+// Also, when you change this from Gecko you may need to regenerate the
+// C++-side bindings (see components/style/cbindgen.toml).
+enum class StyleDisplay : uint8_t {
+  None = 0,
+  Block,
+  FlowRoot,
+  Inline,
+  InlineBlock,
+  ListItem,
+  Table,
+  InlineTable,
+  TableRowGroup,
+  TableColumn,
+  TableColumnGroup,
+  TableHeaderGroup,
+  TableFooterGroup,
+  TableRow,
+  TableCell,
+  TableCaption,
+  Flex,
+  InlineFlex,
+  Grid,
+  InlineGrid,
+  Ruby,
+  RubyBase,
+  RubyBaseContainer,
+  RubyText,
+  RubyTextContainer,
+  Contents,
+  WebkitBox,
+  WebkitInlineBox,
+  MozBox,
+  MozInlineBox,
+  MozGrid,
+  MozInlineGrid,
+  MozGridGroup,
+  MozGridLine,
+  MozStack,
+  MozInlineStack,
+  MozDeck,
+  MozGroupbox,
+  MozPopup,
+};
+
+} // namespace mozilla
--- a/layout/style/moz.build
+++ b/layout/style/moz.build
@@ -78,16 +78,17 @@ EXPORTS.mozilla += [
     'ServoBindings.h',
     'ServoBindingTypes.h',
     'ServoComputedData.h',
     'ServoComputedDataInlines.h',
     'ServoCSSParser.h',
     'ServoCSSRuleList.h',
     'ServoElementSnapshot.h',
     'ServoElementSnapshotTable.h',
+    'ServoStyleConsts.h',
     'ServoStyleSet.h',
     'ServoStyleSetInlines.h',
     'ServoTraversalStatistics.h',
     'ServoTypes.h',
     'ServoUtils.h',
     'SheetType.h',
     'StyleAnimationValue.h',
     'StyleComplexColor.h',
--- a/layout/style/nsStyleConsts.h
+++ b/layout/style/nsStyleConsts.h
@@ -6,18 +6,20 @@
 
 /* constants used in the style struct data provided by ComputedStyle */
 
 #ifndef nsStyleConsts_h___
 #define nsStyleConsts_h___
 
 #include <inttypes.h>
 
+#include "X11UndefineNone.h"
+
 #include "gfxFontConstants.h"
-#include "X11UndefineNone.h"
+#include "mozilla/ServoStyleConsts.h"
 
 // XXX fold this into ComputedStyle and group by nsStyleXXX struct
 
 namespace mozilla {
 
 // Basic shapes
 enum class StyleBasicShapeType : uint8_t {
   Polygon,
@@ -438,65 +440,16 @@ enum class StyleContent : uint8_t {
 #define NS_STYLE_WRITING_MODE_SIDEWAYS_RL         \
           (NS_STYLE_WRITING_MODE_VERTICAL_RL |    \
            NS_STYLE_WRITING_MODE_SIDEWAYS_MASK)
 #define NS_STYLE_WRITING_MODE_SIDEWAYS_LR         \
           (NS_STYLE_WRITING_MODE_VERTICAL_LR |    \
            NS_STYLE_WRITING_MODE_SIDEWAYS_MASK)
 
 // See nsStyleDisplay
-//
-// NOTE: Order is important! If you change it, make sure to take a look at
-// the FrameConstructionDataByDisplay stuff (both the XUL and non-XUL version),
-// and ensure it's still correct!
-enum class StyleDisplay : uint8_t {
-  None = 0,
-  Block,
-  FlowRoot,
-  Inline,
-  InlineBlock,
-  ListItem,
-  Table,
-  InlineTable,
-  TableRowGroup,
-  TableColumn,
-  TableColumnGroup,
-  TableHeaderGroup,
-  TableFooterGroup,
-  TableRow,
-  TableCell,
-  TableCaption,
-  Flex,
-  InlineFlex,
-  Grid,
-  InlineGrid,
-  Ruby,
-  RubyBase,
-  RubyBaseContainer,
-  RubyText,
-  RubyTextContainer,
-  Contents,
-  WebkitBox,
-  WebkitInlineBox,
-  MozBox,
-  MozInlineBox,
-#ifdef MOZ_XUL
-  MozGrid,
-  MozInlineGrid,
-  MozGridGroup,
-  MozGridLine,
-  MozStack,
-  MozInlineStack,
-  MozDeck,
-  MozGroupbox,
-  MozPopup,
-#endif
-};
-
-// See nsStyleDisplay
 // If these are re-ordered, nsComputedDOMStyle::DoGetContain() must be updated.
 #define NS_STYLE_CONTAIN_NONE                   0
 #define NS_STYLE_CONTAIN_SIZE                   0x01
 #define NS_STYLE_CONTAIN_LAYOUT                 0x02
 #define NS_STYLE_CONTAIN_STYLE                  0x04
 #define NS_STYLE_CONTAIN_PAINT                  0x08
 #define NS_STYLE_CONTAIN_STRICT                 0x10
 #define NS_STYLE_CONTAIN_CONTENT                0x20
new file mode 100644
--- /dev/null
+++ b/servo/components/style/cbindgen.toml
@@ -0,0 +1,26 @@
+header = """/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */"""
+autogen_warning = """/* DO NOT MODIFY THIS MANUALLY! This file was generated using cbindgen.
+ * To generate this file:
+ *   1. Get the latest cbindgen using `cargo install --force cbindgen`
+ *      a. Alternatively, you can clone `https://github.com/eqrion/cbindgen` and use a tagged release
+ *   2. Run `rustup run nightly cbindgen toolkit/library/rust/ --lockfile Cargo.lock --crate style -o layout/style/ServoStyleConsts.h`
+ */"""
+include_version = true
+braces = "SameLine"
+line_length = 80
+tab_width = 2
+language = "C++"
+namespaces = ["mozilla"]
+
+[struct]
+derive_eq = true
+
+[enum]
+derive_helper_methods = true
+
+[export]
+prefix = "Style"
+include = ["StyleDisplay"]
+item_types = ["enums"]
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -3026,67 +3026,49 @@ fn static_assert() {
                           scroll-snap-type-x scroll-snap-type-y scroll-snap-coordinate
                           perspective-origin -moz-binding will-change
                           overscroll-behavior-x overscroll-behavior-y
                           overflow-clip-box-inline overflow-clip-box-block
                           perspective-origin -moz-binding will-change
                           shape-outside contain touch-action translate
                           scale""" %>
 <%self:impl_trait style_struct_name="Box" skip_longhands="${skip_box_longhands}">
-
-    // We manually-implement the |display| property until we get general
-    // infrastructure for preffing certain values.
-    <% display_keyword = Keyword("display", "inline block inline-block table inline-table table-row-group " +
-                                            "table-header-group table-footer-group table-row table-column-group " +
-                                            "table-column table-cell table-caption list-item flex none " +
-                                            "inline-flex grid inline-grid ruby ruby-base ruby-base-container " +
-                                            "ruby-text ruby-text-container contents flow-root -webkit-box " +
-                                            "-webkit-inline-box -moz-box -moz-inline-box -moz-grid -moz-inline-grid " +
-                                            "-moz-grid-group -moz-grid-line -moz-stack -moz-inline-stack -moz-deck " +
-                                            "-moz-popup -moz-groupbox",
-                                            gecko_enum_prefix="StyleDisplay",
-                                            gecko_strip_moz_prefix=False) %>
-
-    fn match_display_keyword(
-        v: longhands::display::computed_value::T
-    ) -> structs::root::mozilla::StyleDisplay {
-        use properties::longhands::display::computed_value::T as Keyword;
-        // FIXME(bholley): Align binary representations and ditch |match| for cast + static_asserts
-        match v {
-            % for value in display_keyword.values_for('gecko'):
-                Keyword::${to_camel_case(value)} =>
-                    structs::${display_keyword.gecko_constant(value)},
-            % endfor
-        }
-    }
-
+    #[inline]
     pub fn set_display(&mut self, v: longhands::display::computed_value::T) {
-        let result = Self::match_display_keyword(v);
-        self.gecko.mDisplay = result;
-        self.gecko.mOriginalDisplay = result;
-    }
-
+        // unsafe: cbindgen ensures the representation is the same.
+        self.gecko.mDisplay = unsafe { transmute(v) };
+        self.gecko.mOriginalDisplay = unsafe { transmute(v) };
+    }
+
+    #[inline]
     pub fn copy_display_from(&mut self, other: &Self) {
         self.gecko.mDisplay = other.gecko.mDisplay;
         self.gecko.mOriginalDisplay = other.gecko.mDisplay;
     }
 
+    #[inline]
     pub fn reset_display(&mut self, other: &Self) {
         self.copy_display_from(other)
     }
 
+    #[inline]
     pub fn set_adjusted_display(
         &mut self,
         v: longhands::display::computed_value::T,
         _is_item_or_root: bool
     ) {
-        self.gecko.mDisplay = Self::match_display_keyword(v);
-    }
-
-    <%call expr="impl_keyword_clone('display', 'mDisplay', display_keyword)"></%call>
+        // unsafe: cbindgen ensures the representation is the same.
+        self.gecko.mDisplay = unsafe { transmute(v) };
+    }
+
+    #[inline]
+    pub fn clone_display(&self) -> longhands::display::computed_value::T {
+        // unsafe: cbindgen ensures the representation is the same.
+        unsafe { transmute(self.gecko.mDisplay) }
+    }
 
     <% float_keyword = Keyword("float", "Left Right None", gecko_enum_prefix="StyleFloat") %>
     ${impl_keyword('float', 'mFloat', float_keyword)}
 
     <% clear_keyword = Keyword(
         "clear",
         "Left Right None Both",
         gecko_enum_prefix="StyleClear",
--- a/servo/components/style/values/specified/box.rs
+++ b/servo/components/style/values/specified/box.rs
@@ -36,39 +36,52 @@ fn moz_box_display_values_enabled(contex
     use stylesheets::Origin;
     context.stylesheet_origin == Origin::UserAgent ||
     context.chrome_rules_enabled() ||
     unsafe {
         structs::StaticPrefs_sVarCache_layout_css_xul_box_display_values_content_enabled
     }
 }
 
+/// Defines an element’s display type, which consists of
+/// the two basic qualities of how an element generates boxes
+/// <https://drafts.csswg.org/css-display/#propdef-display>
+///
+///
+/// NOTE(emilio): Order is important in Gecko!
+///
+/// If you change it, make sure to take a look at the
+/// FrameConstructionDataByDisplay stuff (both the XUL and non-XUL version), and
+/// ensure it's still correct!
+///
+/// Also, when you change this from Gecko you may need to regenerate the
+/// C++-side bindings (see components/style/cbindgen.toml).
 #[allow(missing_docs)]
 #[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq,
          SpecifiedValueInfo, ToComputedValue, ToCss)]
 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
-/// Defines an element’s display type, which consists of
-/// the two basic qualities of how an element generates boxes
-/// <https://drafts.csswg.org/css-display/#propdef-display>
+#[repr(u8)]
 pub enum Display {
-    Inline,
+    None = 0,
     Block,
+    #[cfg(feature = "gecko")]
+    FlowRoot,
+    Inline,
     InlineBlock,
+    ListItem,
     Table,
     InlineTable,
     TableRowGroup,
+    TableColumn,
+    TableColumnGroup,
     TableHeaderGroup,
     TableFooterGroup,
     TableRow,
-    TableColumnGroup,
-    TableColumn,
     TableCell,
     TableCaption,
-    ListItem,
-    None,
     #[parse(aliases = "-webkit-flex")]
     Flex,
     #[parse(aliases = "-webkit-inline-flex")]
     InlineFlex,
     #[cfg(feature = "gecko")]
     Grid,
     #[cfg(feature = "gecko")]
     InlineGrid,
@@ -80,18 +93,16 @@ pub enum Display {
     RubyBaseContainer,
     #[cfg(feature = "gecko")]
     RubyText,
     #[cfg(feature = "gecko")]
     RubyTextContainer,
     #[cfg(feature = "gecko")]
     Contents,
     #[cfg(feature = "gecko")]
-    FlowRoot,
-    #[cfg(feature = "gecko")]
     WebkitBox,
     #[cfg(feature = "gecko")]
     WebkitInlineBox,
     #[cfg(feature = "gecko")]
     #[parse(condition = "moz_box_display_values_enabled")]
     MozBox,
     #[cfg(feature = "gecko")]
     #[parse(condition = "moz_box_display_values_enabled")]
@@ -114,20 +125,20 @@ pub enum Display {
     #[cfg(feature = "gecko")]
     #[parse(condition = "moz_display_values_enabled")]
     MozInlineStack,
     #[cfg(feature = "gecko")]
     #[parse(condition = "moz_display_values_enabled")]
     MozDeck,
     #[cfg(feature = "gecko")]
     #[parse(condition = "moz_display_values_enabled")]
-    MozPopup,
+    MozGroupbox,
     #[cfg(feature = "gecko")]
     #[parse(condition = "moz_display_values_enabled")]
-    MozGroupbox,
+    MozPopup,
 }
 
 impl Display {
     /// The initial display value.
     #[inline]
     pub fn inline() -> Self {
         Display::Inline
     }