Bug 1359217 part 1 - Put a pointer of Gecko wrapper object into Servo's StyleRule. r?Manishearth draft
authorXidorn Quan <me@upsuper.org>
Tue, 13 Jun 2017 18:48:44 +1000
changeset 593772 5d6aadc8d59fd8a1b29e683971bf210960f80b86
parent 593662 14ae46d09ee0c6a1686810de416decd470e0ff27
child 593773 4f06a62c6719bcda2a754f114b3ec19d5d6c8027
push id63795
push userxquan@mozilla.com
push dateWed, 14 Jun 2017 03:44:03 +0000
reviewersManishearth
bugs1359217
milestone56.0a1
Bug 1359217 part 1 - Put a pointer of Gecko wrapper object into Servo's StyleRule. r?Manishearth MozReview-Commit-ID: FUi9M5NYIQN
layout/style/ServoBindingList.h
layout/style/ServoBindings.h
layout/style/ServoBindings.toml
layout/style/ServoStyleRule.cpp
servo/components/style/stylesheets/rule_parser.rs
servo/components/style/stylesheets/style_rule.rs
servo/ports/geckolib/glue.rs
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -152,16 +152,19 @@ SERVO_BINDING_FUNC(Servo_StyleRule_GetSe
 SERVO_BINDING_FUNC(Servo_StyleRule_GetSelectorTextAtIndex, void,
                    RawServoStyleRuleBorrowed rule, uint32_t index,
                    nsAString* result)
 SERVO_BINDING_FUNC(Servo_StyleRule_GetSpecificityAtIndex, void,
                    RawServoStyleRuleBorrowed rule, uint32_t index,
                    uint64_t* specificity)
 SERVO_BINDING_FUNC(Servo_StyleRule_GetSelectorCount, void,
                    RawServoStyleRuleBorrowed rule, uint32_t* count)
+SERVO_BINDING_FUNC(Servo_StyleRule_SetGeckoRulePointer, void,
+                   RawServoStyleRuleBorrowed rule,
+                   const mozilla::ServoStyleRule* ptr)
 SERVO_BINDING_FUNC(Servo_ImportRule_GetHref, void,
                    RawServoImportRuleBorrowed rule, nsAString* result)
 SERVO_BINDING_FUNC(Servo_ImportRule_GetSheet, const RawServoStyleSheet*,
                    RawServoImportRuleBorrowed rule)
 SERVO_BINDING_FUNC(Servo_Keyframe_GetKeyText, void,
                    RawServoKeyframeBorrowed keyframe, nsAString* result)
 // Returns whether it successfully changes the key text.
 SERVO_BINDING_FUNC(Servo_Keyframe_SetKeyText, bool,
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -44,16 +44,17 @@ namespace mozilla {
     struct ImageValue;
     class LoaderReusableStyleSheets;
   };
   namespace dom {
     enum class IterationCompositeOperation : uint8_t;
   };
   enum class UpdateAnimationsTasks : uint8_t;
   struct LangGroupFontPrefs;
+  class ServoStyleRule;
   class ServoStyleSheet;
   class ServoElementSnapshotTable;
 }
 using mozilla::FontFamilyList;
 using mozilla::FontFamilyType;
 using mozilla::ServoElementSnapshot;
 class nsCSSCounterStyleRule;
 class nsCSSFontFaceRule;
--- a/layout/style/ServoBindings.toml
+++ b/layout/style/ServoBindings.toml
@@ -112,16 +112,17 @@ whitelist-vars = [
     "kPresContext_.*",
 ]
 whitelist-types = [
     "RawGecko.*",
     "mozilla::AnimationPropertySegment",
     "mozilla::ComputedTiming",
     "mozilla::ComputedTimingFunction",
     "mozilla::ComputedTimingFunction::BeforeFlag",
+    "mozilla::ServoStyleRule",
     "mozilla::ServoStyleSheet",
     "mozilla::ServoElementSnapshot.*",
     "mozilla::CSSPseudoClassType",
     "mozilla::css::SheetParsingMode",
     "mozilla::css::URLMatchingFunction",
     "mozilla::dom::IterationCompositeOperation",
     "mozilla::HalfCorner",
     "mozilla::PropertyStyleAnimationValuePair",
@@ -430,16 +431,17 @@ structs-types = [
     "nsStyleVisibility",
     "nsStyleXUL",
     "nsTimingFunction",
     "nscolor",
     "nscoord",
     "nsresult",
     "Loader",
     "LoaderReusableStyleSheets",
+    "ServoStyleRule",
     "ServoStyleSheet",
     "EffectCompositor_CascadeLevel",
     "UpdateAnimationsTasks",
     "ParsingMode",
     "InheritTarget",
     "URLMatchingFunction",
     "StyleRuleInclusion",
     "nsStyleTransformMatrix::MatrixTransformOperator",
--- a/layout/style/ServoStyleRule.cpp
+++ b/layout/style/ServoStyleRule.cpp
@@ -110,16 +110,17 @@ ServoStyleRuleDeclaration::GetServoCSSPa
 // -- ServoStyleRule --------------------------------------------------
 
 ServoStyleRule::ServoStyleRule(already_AddRefed<RawServoStyleRule> aRawRule,
                                uint32_t aLine, uint32_t aColumn)
   : BindingStyleRule(aLine, aColumn)
   , mRawRule(aRawRule)
   , mDecls(Servo_StyleRule_GetStyle(mRawRule).Consume())
 {
+  Servo_StyleRule_SetGeckoRulePointer(mRawRule, this);
 }
 
 // QueryInterface implementation for ServoStyleRule
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServoStyleRule)
   NS_INTERFACE_MAP_ENTRY(nsICSSStyleRuleDOMWrapper)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSStyleRule)
 NS_INTERFACE_MAP_END_INHERITING(css::Rule)
 
--- a/servo/components/style/stylesheets/rule_parser.rs
+++ b/servo/components/style/stylesheets/rule_parser.rs
@@ -514,16 +514,17 @@ impl<'a, 'b, 'i> QualifiedRuleParser<'i>
         let location = get_location_with_offset(input.current_source_location(),
                                                 self.context.line_number_offset);
         let context = ParserContext::new_with_rule_type(self.context, Some(CssRuleType::Style));
         let declarations = parse_property_declaration_list(&context, input);
         Ok(CssRule::Style(Arc::new(self.shared_lock.wrap(StyleRule {
             selectors: prelude,
             block: Arc::new(self.shared_lock.wrap(declarations)),
             source_location: location,
+            gecko_rule: Default::default(),
         }))))
     }
 }
 
 /// Calculates the location of a rule's source given an offset.
 fn get_location_with_offset(
     location: SourceLocation,
     offset: u64
--- a/servo/components/style/stylesheets/style_rule.rs
+++ b/servo/components/style/stylesheets/style_rule.rs
@@ -1,46 +1,75 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //! A style rule.
 
 use cssparser::SourceLocation;
+#[cfg(feature = "gecko")]
+use gecko_bindings::structs::ServoStyleRule;
 use properties::PropertyDeclarationBlock;
 use selector_parser::SelectorImpl;
 use selectors::SelectorList;
 use shared_lock::{DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
 use std::fmt;
 use style_traits::ToCss;
 use stylearc::Arc;
 use stylesheets::{MallocSizeOf, MallocSizeOfFn, MallocSizeOfWithGuard};
 
+#[cfg(feature = "gecko")]
+#[derive(Debug)]
+pub struct GeckoStyleRule(pub *const ServoStyleRule);
+
+// Pointers don't implement these traits automatically, but StyleRule is
+// required to have them. Don't try to dereference the pointer in Rust.
+#[cfg(feature = "gecko")]
+unsafe impl Send for GeckoStyleRule {}
+#[cfg(feature = "gecko")]
+unsafe impl Sync for GeckoStyleRule {}
+
+#[cfg(feature = "gecko")]
+impl Default for GeckoStyleRule {
+    fn default() -> Self {
+        GeckoStyleRule(::std::ptr::null())
+    }
+}
+
+#[cfg(not(feature = "gecko"))]
+#[derive(Debug, Default)]
+pub struct GeckoStyleRule;
+
 /// A style rule, with selectors and declarations.
 #[derive(Debug)]
 pub struct StyleRule {
     /// The list of selectors in this rule.
     pub selectors: SelectorList<SelectorImpl>,
     /// The declaration block with the properties it contains.
     pub block: Arc<Locked<PropertyDeclarationBlock>>,
     /// The location in the sheet where it was found.
     pub source_location: SourceLocation,
+    /// The reverse pointer to Gecko's wrapper rule object of this rule.
+    /// It may be null if the corresponding wrapper object hasn't been
+    /// constructed in the Gecko side.
+    pub gecko_rule: GeckoStyleRule,
 }
 
 impl DeepCloneWithLock for StyleRule {
     /// Deep clones this StyleRule.
     fn deep_clone_with_lock(
         &self,
         lock: &SharedRwLock,
         guard: &SharedRwLockReadGuard,
     ) -> StyleRule {
         StyleRule {
             selectors: self.selectors.clone(),
             block: Arc::new(lock.wrap(self.block.read_with(guard).clone())),
             source_location: self.source_location.clone(),
+            gecko_rule: Default::default(),
         }
     }
 }
 
 impl MallocSizeOfWithGuard for StyleRule {
     fn malloc_size_of_children(
         &self,
         guard: &SharedRwLockReadGuard,
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -63,17 +63,17 @@ use style::gecko_bindings::bindings::Raw
 use style::gecko_bindings::bindings::RawServoStyleSheet;
 use style::gecko_bindings::bindings::ServoComputedValuesBorrowedOrNull;
 use style::gecko_bindings::bindings::nsTArrayBorrowed_uintptr_t;
 use style::gecko_bindings::bindings::nsTimingFunctionBorrowed;
 use style::gecko_bindings::bindings::nsTimingFunctionBorrowedMut;
 use style::gecko_bindings::structs;
 use style::gecko_bindings::structs::{CSSPseudoElementType, CompositeOperation};
 use style::gecko_bindings::structs::{Loader, LoaderReusableStyleSheets};
-use style::gecko_bindings::structs::{RawServoStyleRule, ServoStyleSheet};
+use style::gecko_bindings::structs::{RawServoStyleRule, ServoStyleRule, ServoStyleSheet};
 use style::gecko_bindings::structs::{SheetParsingMode, nsIAtom, nsCSSPropertyID};
 use style::gecko_bindings::structs::{nsCSSFontFaceRule, nsCSSCounterStyleRule};
 use style::gecko_bindings::structs::{nsRestyleHint, nsChangeHint, PropertyValuePair};
 use style::gecko_bindings::structs::IterationCompositeOperation;
 use style::gecko_bindings::structs::MallocSizeOf;
 use style::gecko_bindings::structs::RawGeckoGfxMatrix4x4;
 use style::gecko_bindings::structs::RawGeckoPresContextOwned;
 use style::gecko_bindings::structs::ServoElementSnapshotTable;
@@ -1217,16 +1217,25 @@ pub extern "C" fn Servo_StyleRule_GetSpe
             *specificity = 0;
             return;
         }
         *specificity = rule.selectors.0[index].selector.specificity() as u64;
     })
 }
 
 #[no_mangle]
+pub extern "C" fn Servo_StyleRule_SetGeckoRulePointer(rule: RawServoStyleRuleBorrowed,
+                                                      ptr: *const ServoStyleRule) {
+    write_locked_arc(rule, |rule: &mut StyleRule| {
+        debug_assert_eq!(rule.gecko_rule.0, ptr::null());
+        rule.gecko_rule.0 = ptr;
+    })
+}
+
+#[no_mangle]
 pub extern "C" fn Servo_ImportRule_GetHref(rule: RawServoImportRuleBorrowed, result: *mut nsAString) {
     read_locked_arc(rule, |rule: &ImportRule| {
         write!(unsafe { &mut *result }, "{}", rule.url.as_str()).unwrap();
     })
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_ImportRule_GetSheet(rule: RawServoImportRuleBorrowed) -> *const RawServoStyleSheet {