servo: Merge #15682 - Simplify defining arc ffi types (from upsuper:arc-types); r=Manishearth
authorXidorn Quan <me@upsuper.org>
Wed, 22 Feb 2017 15:58:35 -0800
changeset 373371 e4f1979be0d7e681b6ee68ebf4812b1e68c0f9d8
parent 373370 4799fdd232958d83efc92b36d5b384bf0503972a
child 373372 f413492608a60e5ea8b0c16fd2f847f3c0a387f0
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersManishearth
milestone54.0a1
servo: Merge #15682 - Simplify defining arc ffi types (from upsuper:arc-types); r=Manishearth r? @Manishearth I don't have a good sense for creating syntax... so if you have any suggestion for the syntax of `impl_arc_ffi` macro, it would be appreciated. Source-Repo: https://github.com/servo/servo Source-Revision: af292c4a7180a35c632b16a4fb0aff9ae2933f77
servo/components/style/gecko/arc_types.rs
servo/components/style/gecko/conversions.rs
servo/components/style/gecko/mod.rs
servo/components/style/properties/helpers/animated_properties.mako.rs
servo/ports/geckolib/glue.rs
servo/tests/unit/stylo/check_bindings.py
new file mode 100644
--- /dev/null
+++ b/servo/components/style/gecko/arc_types.rs
@@ -0,0 +1,58 @@
+/* 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/. */
+
+//! This file lists all arc FFI types and defines corresponding addref
+//! and release functions. This list corresponds to ServoArcTypeList.h
+//! file in Gecko.
+
+#![allow(non_snake_case, missing_docs)]
+
+use gecko_bindings::bindings::{RawServoStyleSheet, RawServoStyleRule, RawServoImportRule};
+use gecko_bindings::bindings::{ServoComputedValues, ServoCssRules};
+use gecko_bindings::structs::{RawServoAnimationValue, RawServoDeclarationBlock};
+use gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI};
+use parking_lot::RwLock;
+use properties::{ComputedValues, PropertyDeclarationBlock};
+use properties::animated_properties::AnimationValue;
+use stylesheets::{CssRules, Stylesheet, StyleRule, ImportRule};
+
+macro_rules! impl_arc_ffi {
+    ($servo_type:ty => $gecko_type:ty [$addref:ident, $release:ident]) => {
+        unsafe impl HasFFI for $servo_type {
+            type FFIType = $gecko_type;
+        }
+        unsafe impl HasArcFFI for $servo_type {}
+
+        #[no_mangle]
+        pub unsafe extern "C" fn $addref(obj: &$gecko_type) -> () {
+            <$servo_type>::addref(obj);
+        }
+
+        #[no_mangle]
+        pub unsafe extern "C" fn $release(obj: &$gecko_type) -> () {
+            <$servo_type>::release(obj);
+        }
+    }
+}
+
+impl_arc_ffi!(RwLock<CssRules> => ServoCssRules
+              [Servo_CssRules_AddRef, Servo_CssRules_Release]);
+
+impl_arc_ffi!(Stylesheet => RawServoStyleSheet
+              [Servo_StyleSheet_AddRef, Servo_StyleSheet_Release]);
+
+impl_arc_ffi!(ComputedValues => ServoComputedValues
+              [Servo_ComputedValues_AddRef, Servo_ComputedValues_Release]);
+
+impl_arc_ffi!(RwLock<PropertyDeclarationBlock> => RawServoDeclarationBlock
+              [Servo_DeclarationBlock_AddRef, Servo_DeclarationBlock_Release]);
+
+impl_arc_ffi!(RwLock<StyleRule> => RawServoStyleRule
+              [Servo_StyleRule_AddRef, Servo_StyleRule_Release]);
+
+impl_arc_ffi!(RwLock<ImportRule> => RawServoImportRule
+              [Servo_ImportRule_AddRef, Servo_ImportRule_Release]);
+
+impl_arc_ffi!(AnimationValue => RawServoAnimationValue
+              [Servo_AnimationValue_AddRef, Servo_AnimationValue_Release]);
--- a/servo/components/style/gecko/conversions.rs
+++ b/servo/components/style/gecko/conversions.rs
@@ -6,57 +6,22 @@
 //! Ideally, it would be in geckolib itself, but coherence
 //! forces us to keep the traits and implementations here
 
 #![allow(unsafe_code)]
 
 use app_units::Au;
 use gecko::values::convert_rgba_to_nscolor;
 use gecko_bindings::bindings::{Gecko_CreateGradient, Gecko_SetGradientImageValue, Gecko_SetUrlImageValue};
-use gecko_bindings::bindings::{RawServoStyleSheet, RawServoStyleRule, RawServoImportRule};
-use gecko_bindings::bindings::{ServoComputedValues, ServoCssRules};
 use gecko_bindings::structs::{nsStyleCoord_CalcValue, nsStyleImage};
-use gecko_bindings::structs::RawServoDeclarationBlock;
 use gecko_bindings::structs::nsresult;
 use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordDataMut};
-use gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI};
-use parking_lot::RwLock;
-use properties::{ComputedValues, PropertyDeclarationBlock};
-use stylesheets::{CssRules, RulesMutateError, Stylesheet, StyleRule, ImportRule};
+use stylesheets::RulesMutateError;
 use values::computed::{CalcLengthOrPercentage, Gradient, Image, LengthOrPercentage, LengthOrPercentageOrAuto};
 
-unsafe impl HasFFI for Stylesheet {
-    type FFIType = RawServoStyleSheet;
-}
-unsafe impl HasArcFFI for Stylesheet {}
-unsafe impl HasFFI for ComputedValues {
-    type FFIType = ServoComputedValues;
-}
-unsafe impl HasArcFFI for ComputedValues {}
-
-unsafe impl HasFFI for RwLock<PropertyDeclarationBlock> {
-    type FFIType = RawServoDeclarationBlock;
-}
-unsafe impl HasArcFFI for RwLock<PropertyDeclarationBlock> {}
-
-unsafe impl HasFFI for RwLock<CssRules> {
-    type FFIType = ServoCssRules;
-}
-unsafe impl HasArcFFI for RwLock<CssRules> {}
-
-unsafe impl HasFFI for RwLock<StyleRule> {
-    type FFIType = RawServoStyleRule;
-}
-unsafe impl HasArcFFI for RwLock<StyleRule> {}
-
-unsafe impl HasFFI for RwLock<ImportRule> {
-    type FFIType = RawServoImportRule;
-}
-unsafe impl HasArcFFI for RwLock<ImportRule> {}
-
 impl From<CalcLengthOrPercentage> for nsStyleCoord_CalcValue {
     fn from(other: CalcLengthOrPercentage) -> nsStyleCoord_CalcValue {
         let has_percentage = other.percentage.is_some();
         nsStyleCoord_CalcValue {
             mLength: other.length.0,
             mPercent: other.percentage.unwrap_or(0.0),
             mHasPercent: has_percentage,
         }
--- a/servo/components/style/gecko/mod.rs
+++ b/servo/components/style/gecko/mod.rs
@@ -1,14 +1,15 @@
 /* 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/. */
 
 //! Gecko-specific style-system bits.
 
+pub mod arc_types;
 pub mod conversions;
 pub mod data;
 pub mod media_queries;
 pub mod restyle_damage;
 pub mod selector_parser;
 pub mod snapshot;
 pub mod snapshot_helpers;
 pub mod traversal;
--- a/servo/components/style/properties/helpers/animated_properties.mako.rs
+++ b/servo/components/style/properties/helpers/animated_properties.mako.rs
@@ -227,27 +227,16 @@ impl AnimatedProperty {
                             new_style.get_${prop.style_struct.ident.strip("_")}().clone_${prop.ident}())
                     }
                 % endif
             % endfor
         }
     }
 }
 
-
-% if product == "gecko":
-    use gecko_bindings::structs::RawServoAnimationValue;
-    use gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI};
-
-    unsafe impl HasFFI for AnimationValue {
-        type FFIType = RawServoAnimationValue;
-    }
-    unsafe impl HasArcFFI for AnimationValue {}
-% endif
-
 /// An enum to represent a single computed value belonging to an animated
 /// property in order to be interpolated with another one. When interpolating,
 /// both values need to belong to the same property.
 ///
 /// This is different to AnimatedProperty in the sense that AnimatedProperty
 /// also knows the final value to be used during the animation.
 ///
 /// This is to be used in Gecko integration code.
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -327,27 +327,16 @@ pub extern "C" fn Servo_AnimationValues_
 
     // we should have gone through both iterators
     if iter.next().is_some() || geckoiter.next().is_some() {
         warn!("stylo: Mismatched sizes of Gecko and Servo \
                array during animation value construction");
     }
 }
 
-
-#[no_mangle]
-pub extern "C" fn Servo_AnimationValue_AddRef(anim: RawServoAnimationValueBorrowed) -> () {
-    unsafe { AnimationValue::addref(anim) };
-}
-
-#[no_mangle]
-pub extern "C" fn Servo_AnimationValue_Release(anim: RawServoAnimationValueBorrowed) -> () {
-    unsafe { AnimationValue::release(anim) };
-}
-
 #[no_mangle]
 pub extern "C" fn Servo_StyleWorkerThreadCount() -> u32 {
     *NUM_THREADS as u32
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_Element_ClearData(element: RawGeckoElementBorrowed) -> () {
     GeckoElement(element).clear_data();
@@ -526,26 +515,16 @@ pub extern "C" fn Servo_StyleSheet_HasRu
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_StyleSheet_GetRules(sheet: RawServoStyleSheetBorrowed) -> ServoCssRulesStrong {
     Stylesheet::as_arc(&sheet).rules.clone().into_strong()
 }
 
 #[no_mangle]
-pub extern "C" fn Servo_StyleSheet_AddRef(sheet: RawServoStyleSheetBorrowed) -> () {
-    unsafe { Stylesheet::addref(sheet) };
-}
-
-#[no_mangle]
-pub extern "C" fn Servo_StyleSheet_Release(sheet: RawServoStyleSheetBorrowed) -> () {
-    unsafe { Stylesheet::release(sheet) };
-}
-
-#[no_mangle]
 pub extern "C" fn Servo_CssRules_ListTypes(rules: ServoCssRulesBorrowed,
                                            result: nsTArrayBorrowed_uintptr_t) -> () {
     let rules = RwLock::<CssRules>::as_arc(&rules).read();
     let iter = rules.0.iter().map(|rule| rule.rule_type() as usize);
     let (size, upper) = iter.size_hint();
     debug_assert_eq!(size, upper.unwrap());
     unsafe { result.set_len(size as u32) };
     result.iter_mut().zip(iter).fold((), |_, (r, v)| *r = v);
@@ -584,36 +563,16 @@ pub extern "C" fn Servo_CssRules_DeleteR
     let rules = RwLock::<CssRules>::as_arc(&rules);
     match rules.write().remove_rule(index as usize) {
         Ok(_) => nsresult::NS_OK,
         Err(err) => err.into()
     }
 }
 
 #[no_mangle]
-pub extern "C" fn Servo_CssRules_AddRef(rules: ServoCssRulesBorrowed) -> () {
-    unsafe { RwLock::<CssRules>::addref(rules) };
-}
-
-#[no_mangle]
-pub extern "C" fn Servo_CssRules_Release(rules: ServoCssRulesBorrowed) -> () {
-    unsafe { RwLock::<CssRules>::release(rules) };
-}
-
-#[no_mangle]
-pub extern "C" fn Servo_StyleRule_AddRef(rule: RawServoStyleRuleBorrowed) -> () {
-    unsafe { RwLock::<StyleRule>::addref(rule) };
-}
-
-#[no_mangle]
-pub extern "C" fn Servo_StyleRule_Release(rule: RawServoStyleRuleBorrowed) -> () {
-    unsafe { RwLock::<StyleRule>::release(rule) };
-}
-
-#[no_mangle]
 pub extern "C" fn Servo_StyleRule_Debug(rule: RawServoStyleRuleBorrowed, result: *mut nsACString) -> () {
     let rule = RwLock::<StyleRule>::as_arc(&rule);
     let result = unsafe { result.as_mut().unwrap() };
     write!(result, "{:?}", *rule.read()).unwrap();
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_StyleRule_GetStyle(rule: RawServoStyleRuleBorrowed) -> RawServoDeclarationBlockStrong {
@@ -637,26 +596,16 @@ pub extern "C" fn Servo_StyleRule_GetCss
 
 #[no_mangle]
 pub extern "C" fn Servo_StyleRule_GetSelectorText(rule: RawServoStyleRuleBorrowed, result: *mut nsAString) -> () {
     let rule = RwLock::<StyleRule>::as_arc(&rule);
     rule.read().selectors.to_css(unsafe { result.as_mut().unwrap() }).unwrap();
 }
 
 #[no_mangle]
-pub extern "C" fn Servo_ImportRule_AddRef(rule: RawServoImportRuleBorrowed) -> () {
-    unsafe { RwLock::<ImportRule>::addref(rule) };
-}
-
-#[no_mangle]
-pub extern "C" fn Servo_ImportRule_Release(rule: RawServoImportRuleBorrowed) -> () {
-    unsafe { RwLock::<ImportRule>::release(rule) };
-}
-
-#[no_mangle]
 pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: ServoComputedValuesBorrowedOrNull,
                                                          pseudo_tag: *mut nsIAtom,
                                                          raw_data: RawServoStyleSetBorrowed)
      -> ServoComputedValuesStrong {
     let data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
     let atom = Atom::from(pseudo_tag);
     let pseudo = PseudoElement::from_atom_unchecked(atom, /* anon_box = */ true);
 
@@ -722,26 +671,16 @@ pub extern "C" fn Servo_ComputedValues_I
     let style = if let Some(reference) = maybe_arc.as_ref() {
         ComputedValues::inherit_from(reference, &data.default_computed_values())
     } else {
         data.default_computed_values().clone()
     };
     style.into_strong()
 }
 
-#[no_mangle]
-pub extern "C" fn Servo_ComputedValues_AddRef(ptr: ServoComputedValuesBorrowed) {
-    unsafe { ComputedValues::addref(ptr) };
-}
-
-#[no_mangle]
-pub extern "C" fn Servo_ComputedValues_Release(ptr: ServoComputedValuesBorrowed) {
-    unsafe { ComputedValues::release(ptr) };
-}
-
 /// See the comment in `Device` to see why it's ok to pass an owned reference to
 /// the pres context (hint: the context outlives the StyleSet, that holds the
 /// device alive).
 #[no_mangle]
 pub extern "C" fn Servo_StyleSet_Init(pres_context: RawGeckoPresContextOwned)
   -> RawServoStyleSetOwned {
     let data = Box::new(PerDocumentStyleData::new(pres_context));
     data.into_ffi()
@@ -810,26 +749,16 @@ pub extern "C" fn Servo_DeclarationBlock
 #[no_mangle]
 pub extern "C" fn Servo_DeclarationBlock_Clone(declarations: RawServoDeclarationBlockBorrowed)
                                                -> RawServoDeclarationBlockStrong {
     let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
     Arc::new(RwLock::new(declarations.read().clone())).into_strong()
 }
 
 #[no_mangle]
-pub extern "C" fn Servo_DeclarationBlock_AddRef(declarations: RawServoDeclarationBlockBorrowed) {
-    unsafe { RwLock::<PropertyDeclarationBlock>::addref(declarations) };
-}
-
-#[no_mangle]
-pub extern "C" fn Servo_DeclarationBlock_Release(declarations: RawServoDeclarationBlockBorrowed) {
-    unsafe { RwLock::<PropertyDeclarationBlock>::release(declarations) };
-}
-
-#[no_mangle]
 pub extern "C" fn Servo_DeclarationBlock_Equals(a: RawServoDeclarationBlockBorrowed,
                                                 b: RawServoDeclarationBlockBorrowed)
                                                 -> bool {
     *RwLock::<PropertyDeclarationBlock>::as_arc(&a).read() == *RwLock::<PropertyDeclarationBlock>::as_arc(&b).read()
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_DeclarationBlock_GetCssText(declarations: RawServoDeclarationBlockBorrowed,
--- a/servo/tests/unit/stylo/check_bindings.py
+++ b/servo/tests/unit/stylo/check_bindings.py
@@ -28,10 +28,11 @@ with open(INPUT_FILE, "r") as bindings, 
         # GetStyleVariables is a Servo_* function, but temporarily defined on
         # the gecko side
         if match and match.group(1) != "GetStyleVariables":
             tests.write(TEMPLATE.format(name=match.group(1)))
 
     tests.write("}\n")
 
 with open(GLUE_FILE, "r") as glue, open(GLUE_OUTPUT_FILE, "w+") as glue_output:
+    glue_output.write("pub use style::gecko::arc_types::*;")
     for line in glue:
         glue_output.write(line.replace("pub extern \"C\" fn", "pub unsafe extern \"C\" fn"))