Skip to content

Instantly share code, notes, and snippets.

@Manishearth
Created October 13, 2016 08:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Manishearth/c63fb0d6b8db99d92515fb79e28830e3 to your computer and use it in GitHub Desktop.
Save Manishearth/c63fb0d6b8db99d92515fb79e28830e3 to your computer and use it in GitHub Desktop.
diff --git a/layout/style/ServoBindings.cpp b/layout/style/ServoBindings.cpp
index 5e0c78a..bbb3f51 100644
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -313,7 +313,7 @@ Gecko_StoreStyleDifference(RawGeckoNodeBorrowed aNode, nsChangeHint aChangeHintT
#endif
}
-RawServoDeclarationBlock*
+RawServoDeclarationBlockStrongBorrowedOrNull
Gecko_GetServoDeclarationBlock(RawGeckoElementBorrowed aElement)
{
const nsAttrValue* attr = aElement->GetParsedAttr(nsGkAtoms::style);
@@ -324,7 +324,7 @@ Gecko_GetServoDeclarationBlock(RawGeckoElementBorrowed aElement)
if (!decl || decl->IsGecko()) {
return nullptr;
}
- return decl->AsServo()->Raw();
+ return reinterpret_cast<RawServoDeclarationBlockStrongBorrowedOrNull>(const_cast<RawServoDeclarationBlock**>(&decl->AsServo()->Raw()));
}
void
diff --git a/layout/style/ServoBindings.h b/layout/style/ServoBindings.h
index 2d4e4a6..e544a60 100644
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -102,6 +102,7 @@ using mozilla::dom::StyleChildrenIterator;
DECL_ARC_REF_TYPE_FOR(ServoComputedValues)
DECL_ARC_REF_TYPE_FOR(RawServoStyleSheet)
DECL_ARC_REF_TYPE_FOR(RawServoDeclarationBlock)
+DECL_NULLABLE_BORROWED_REF_TYPE_FOR(RawServoDeclarationBlockStrong)
DECL_OWNED_REF_TYPE_FOR(RawServoStyleSet)
DECL_NULLABLE_OWNED_REF_TYPE_FOR(StyleChildrenIterator)
@@ -216,7 +217,7 @@ SERVO_DECLARE_ELEMENT_ATTR_MATCHING_FUNCTIONS(Gecko_Snapshot,
#undef SERVO_DECLARE_ELEMENT_ATTR_MATCHING_FUNCTIONS
// Style attributes.
-RawServoDeclarationBlockBorrowedOrNull
+RawServoDeclarationBlockStrongBorrowedOrNull
Gecko_GetServoDeclarationBlock(RawGeckoElementBorrowed element);
// Atoms.
diff --git a/layout/style/ServoDeclarationBlock.h b/layout/style/ServoDeclarationBlock.h
index 16b26bd..edc02e1 100644
--- a/layout/style/ServoDeclarationBlock.h
+++ b/layout/style/ServoDeclarationBlock.h
@@ -19,7 +19,9 @@ public:
static already_AddRefed<ServoDeclarationBlock>
FromStyleAttribute(const nsAString& aString);
- RawServoDeclarationBlock* Raw() const { return mRaw; }
+ RawServoDeclarationBlock* const& Raw() const {
+ return *reinterpret_cast<RawServoDeclarationBlock* const*>(mRaw.get_address());
+ }
protected:
ServoDeclarationBlock(already_AddRefed<RawServoDeclarationBlock> aRaw)
diff --git a/servo/components/style/binding_tools/regen.py b/servo/components/style/binding_tools/regen.py
index fc0cc24..8e775e54 100755
--- a/servo/components/style/binding_tools/regen.py
+++ b/servo/components/style/binding_tools/regen.py
@@ -242,6 +242,7 @@ COMPILATION_TARGETS = {
"RawGeckoNode",
"RawGeckoElement",
"RawGeckoDocument",
+ "RawServoDeclarationBlockStrong",
],
"whitelist_functions": [
"Servo_.*",
diff --git a/servo/components/style/gecko/wrapper.rs b/servo/components/style/gecko/wrapper.rs
index 398e114..c4f5f36 100644
--- a/servo/components/style/gecko/wrapper.rs
+++ b/servo/components/style/gecko/wrapper.rs
@@ -30,7 +30,7 @@ use gecko_bindings::structs::{NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO, NODE_IS_DIRT
use gecko_bindings::structs::{RawGeckoDocument, RawGeckoElement, RawGeckoNode};
use gecko_bindings::structs::{nsChangeHint, nsIAtom, nsIContent, nsStyleContext};
use gecko_bindings::structs::OpaqueStyleData;
-use gecko_bindings::sugar::ownership::{FFIArcHelpers, HasArcFFI};
+use gecko_bindings::sugar::ownership::FFIArcHelpers;
use libc::uintptr_t;
use parking_lot::RwLock;
use parser::ParserContextExtraData;
@@ -482,8 +482,7 @@ impl<'le> TElement for GeckoElement<'le> {
fn style_attribute(&self) -> Option<&Arc<RwLock<PropertyDeclarationBlock>>> {
let declarations = unsafe { Gecko_GetServoDeclarationBlock(self.0) };
- RwLock::<PropertyDeclarationBlock>::arc_from_borrowed(&declarations)
- .map(|decl| decl as *const Arc<_>).map(|ptr| unsafe { &*ptr })
+ declarations.map(|s| s.into_arc_opt_borrow()).unwrap_or(None)
}
fn get_state(&self) -> ElementState {
diff --git a/servo/components/style/gecko_bindings/bindings.rs b/servo/components/style/gecko_bindings/bindings.rs
index 1a05e81..3df0348 100644
--- a/servo/components/style/gecko_bindings/bindings.rs
+++ b/servo/components/style/gecko_bindings/bindings.rs
@@ -21,6 +21,8 @@ pub type RawGeckoElementBorrowed<'a> = &'a RawGeckoElement;
pub type RawGeckoElementBorrowedOrNull<'a> = Option<&'a RawGeckoElement>;
pub type RawGeckoDocumentBorrowed<'a> = &'a RawGeckoDocument;
pub type RawGeckoDocumentBorrowedOrNull<'a> = Option<&'a RawGeckoDocument>;
+pub type RawServoDeclarationBlockStrongBorrowed<'a> = &'a RawServoDeclarationBlockStrong;
+pub type RawServoDeclarationBlockStrongBorrowedOrNull<'a> = Option<&'a RawServoDeclarationBlockStrong>;
pub type RawServoStyleSetBorrowed<'a> = &'a RawServoStyleSet;
pub type RawServoStyleSetBorrowedMut<'a> = &'a mut RawServoStyleSet;
pub type RawServoStyleSetOwned = ::gecko_bindings::sugar::ownership::Owned<RawServoStyleSet>;
@@ -359,7 +361,7 @@ extern "C" {
}
extern "C" {
pub fn Gecko_GetServoDeclarationBlock(element: RawGeckoElementBorrowed)
- -> RawServoDeclarationBlockBorrowedOrNull;
+ -> RawServoDeclarationBlockStrongBorrowedOrNull;
}
extern "C" {
pub fn Gecko_Atomize(aString: *const ::std::os::raw::c_char, aLength: u32)
diff --git a/servo/components/style/gecko_bindings/sugar/ownership.rs b/servo/components/style/gecko_bindings/sugar/ownership.rs
index bd31483..de29c2d 100644
--- a/servo/components/style/gecko_bindings/sugar/ownership.rs
+++ b/servo/components/style/gecko_bindings/sugar/ownership.rs
@@ -162,6 +162,20 @@ impl<T> Strong<T> {
}
#[inline]
+ /// Given a reference to a strong FFI reference,
+ /// converts it into a reference to a servo-side Arc
+ /// Returns None on null.
+ ///
+ /// Strong<GeckoType> -> Arc<ServoType>
+ pub fn into_arc_opt_borrow<U>(&self) -> Option<&Arc<U>> where U: HasArcFFI<FFIType = T> {
+ if self.is_null() {
+ None
+ } else {
+ unsafe { Some(transmute(self)) }
+ }
+ }
+
+ #[inline]
/// Produces a null strong FFI reference
pub fn null() -> Self {
unsafe { transmute(ptr::null::<T>()) }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment