Bug 1359217 part 1 - Put a pointer of Gecko wrapper object into Servo's StyleRule. r?Manishearth
MozReview-Commit-ID: FUi9M5NYIQN
--- 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 {