diff --git a/components/style/gecko/arc_types.rs b/components/style/gecko/arc_types.rs index 8a213df9324..b2835abdfd0 100644 --- a/components/style/gecko/arc_types.rs +++ b/components/style/gecko/arc_types.rs @@ -2,22 +2,12 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://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. +//! This file lists all arc FFI types and defines corresponding addref and release functions. This +//! list loosely corresponds to ServoLockedArcTypeList.h file in Gecko. #![allow(non_snake_case, missing_docs)] use crate::gecko::url::CssUrlData; -use crate::gecko_bindings::structs::{ - RawServoContainerRule, RawServoCounterStyleRule, RawServoDeclarationBlock, - RawServoFontFaceRule, RawServoFontFeatureValuesRule, RawServoFontPaletteValuesRule, - RawServoImportRule, RawServoKeyframe, RawServoKeyframesRule, RawServoLayerBlockRule, - RawServoLayerStatementRule, RawServoMediaList, RawServoMediaRule, RawServoMozDocumentRule, - RawServoNamespaceRule, RawServoPageRule, RawServoStyleRule, RawServoSupportsRule, - ServoCssRules, -}; -use crate::gecko_bindings::sugar::ownership::HasArcFFI; use crate::media_queries::MediaList; use crate::properties::animated_properties::AnimationValue; use crate::properties::{ComputedValues, PropertyDeclarationBlock}; @@ -30,81 +20,6 @@ use crate::stylesheets::{ }; use servo_arc::Arc; -macro_rules! impl_arc_ffi { - ($servo_type:ty => $gecko_type:ty[$addref:ident, $release:ident]) => { - unsafe impl HasArcFFI for $servo_type { - type FFIType = $gecko_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!(Locked => ServoCssRules - [Servo_CssRules_AddRef, Servo_CssRules_Release]); - -impl_arc_ffi!(Locked => RawServoDeclarationBlock - [Servo_DeclarationBlock_AddRef, Servo_DeclarationBlock_Release]); - -impl_arc_ffi!(Locked => RawServoStyleRule - [Servo_StyleRule_AddRef, Servo_StyleRule_Release]); - -impl_arc_ffi!(Locked => RawServoImportRule - [Servo_ImportRule_AddRef, Servo_ImportRule_Release]); - -impl_arc_ffi!(Locked => RawServoKeyframe - [Servo_Keyframe_AddRef, Servo_Keyframe_Release]); - -impl_arc_ffi!(Locked => RawServoKeyframesRule - [Servo_KeyframesRule_AddRef, Servo_KeyframesRule_Release]); - -impl_arc_ffi!(Locked => RawServoLayerBlockRule - [Servo_LayerBlockRule_AddRef, Servo_LayerBlockRule_Release]); - -impl_arc_ffi!(Locked => RawServoLayerStatementRule - [Servo_LayerStatementRule_AddRef, Servo_LayerStatementRule_Release]); - -impl_arc_ffi!(Locked => RawServoMediaList - [Servo_MediaList_AddRef, Servo_MediaList_Release]); - -impl_arc_ffi!(Locked => RawServoMediaRule - [Servo_MediaRule_AddRef, Servo_MediaRule_Release]); - -impl_arc_ffi!(Locked => RawServoNamespaceRule - [Servo_NamespaceRule_AddRef, Servo_NamespaceRule_Release]); - -impl_arc_ffi!(Locked => RawServoPageRule - [Servo_PageRule_AddRef, Servo_PageRule_Release]); - -impl_arc_ffi!(Locked => RawServoSupportsRule - [Servo_SupportsRule_AddRef, Servo_SupportsRule_Release]); - -impl_arc_ffi!(Locked => RawServoContainerRule - [Servo_ContainerRule_AddRef, Servo_ContainerRule_Release]); - -impl_arc_ffi!(Locked => RawServoMozDocumentRule - [Servo_DocumentRule_AddRef, Servo_DocumentRule_Release]); - -impl_arc_ffi!(Locked => RawServoFontFeatureValuesRule - [Servo_FontFeatureValuesRule_AddRef, Servo_FontFeatureValuesRule_Release]); - -impl_arc_ffi!(Locked => RawServoFontPaletteValuesRule - [Servo_FontPaletteValuesRule_AddRef, Servo_FontPaletteValuesRule_Release]); - -impl_arc_ffi!(Locked => RawServoFontFaceRule - [Servo_FontFaceRule_AddRef, Servo_FontFaceRule_Release]); - -impl_arc_ffi!(Locked => RawServoCounterStyleRule - [Servo_CounterStyleRule_AddRef, Servo_CounterStyleRule_Release]); - macro_rules! impl_simple_arc_ffi { ($ty:ty, $addref:ident, $release:ident) => { #[no_mangle] @@ -119,6 +34,129 @@ macro_rules! impl_simple_arc_ffi { }; } +macro_rules! impl_locked_arc_ffi { + ($servo_type:ty, $alias:ident, $addref:ident, $release:ident) => { + /// A simple alias for a locked type. + pub type $alias = Locked<$servo_type>; + impl_simple_arc_ffi!($alias, $addref, $release); + }; +} + +impl_locked_arc_ffi!( + CssRules, + LockedCssRules, + Servo_CssRules_AddRef, + Servo_CssRules_Release +); +impl_locked_arc_ffi!( + PropertyDeclarationBlock, + LockedDeclarationBlock, + Servo_DeclarationBlock_AddRef, + Servo_DeclarationBlock_Release +); +impl_locked_arc_ffi!( + StyleRule, + LockedStyleRule, + Servo_StyleRule_AddRef, + Servo_StyleRule_Release +); +impl_locked_arc_ffi!( + ImportRule, + LockedImportRule, + Servo_ImportRule_AddRef, + Servo_ImportRule_Release +); +impl_locked_arc_ffi!( + Keyframe, + LockedKeyframe, + Servo_Keyframe_AddRef, + Servo_Keyframe_Release +); +impl_locked_arc_ffi!( + KeyframesRule, + LockedKeyframesRule, + Servo_KeyframesRule_AddRef, + Servo_KeyframesRule_Release +); +impl_locked_arc_ffi!( + LayerBlockRule, + LockedLayerBlockRule, + Servo_LayerBlockRule_AddRef, + Servo_LayerBlockRule_Release +); +impl_locked_arc_ffi!( + LayerStatementRule, + LockedLayerStatementRule, + Servo_LayerStatementRule_AddRef, + Servo_LayerStatementRule_Release +); +impl_locked_arc_ffi!( + MediaList, + LockedMediaList, + Servo_MediaList_AddRef, + Servo_MediaList_Release +); +impl_locked_arc_ffi!( + MediaRule, + LockedMediaRule, + Servo_MediaRule_AddRef, + Servo_MediaRule_Release +); +impl_locked_arc_ffi!( + NamespaceRule, + LockedNamespaceRule, + Servo_NamespaceRule_AddRef, + Servo_NamespaceRule_Release +); +impl_locked_arc_ffi!( + PageRule, + LockedPageRule, + Servo_PageRule_AddRef, + Servo_PageRule_Release +); +impl_locked_arc_ffi!( + SupportsRule, + LockedSupportsRule, + Servo_SupportsRule_AddRef, + Servo_SupportsRule_Release +); +impl_locked_arc_ffi!( + ContainerRule, + LockedContainerRule, + Servo_ContainerRule_AddRef, + Servo_ContainerRule_Release +); +impl_locked_arc_ffi!( + DocumentRule, + LockedDocumentRule, + Servo_DocumentRule_AddRef, + Servo_DocumentRule_Release +); +impl_locked_arc_ffi!( + FontFeatureValuesRule, + LockedFontFeatureValuesRule, + Servo_FontFeatureValuesRule_AddRef, + Servo_FontFeatureValuesRule_Release +); +impl_locked_arc_ffi!( + FontPaletteValuesRule, + LockedFontPaletteValuesRule, + Servo_FontPaletteValuesRule_AddRef, + Servo_FontPaletteValuesRule_Release +); +impl_locked_arc_ffi!( + FontFaceRule, + LockedFontFaceRule, + Servo_FontFaceRule_AddRef, + Servo_FontFaceRule_Release +); +impl_locked_arc_ffi!( + CounterStyleRule, + LockedCounterStyleRule, + Servo_CounterStyleRule_AddRef, + Servo_CounterStyleRule_Release +); + impl_simple_arc_ffi!( StylesheetContents, Servo_StyleSheetContents_AddRef, diff --git a/components/style/gecko/data.rs b/components/style/gecko/data.rs index 50c827bf62f..169ae1668ae 100644 --- a/components/style/gecko/data.rs +++ b/components/style/gecko/data.rs @@ -7,12 +7,11 @@ use crate::dom::TElement; use crate::gecko_bindings::bindings; use crate::gecko_bindings::structs::{self, ServoStyleSetSizes, StyleSheet as DomStyleSheet, StyleSheetInfo}; -use crate::gecko_bindings::sugar::ownership::HasArcFFI; use crate::invalidation::media_queries::{MediaListKey, ToMediaListKey}; use crate::media_queries::{Device, MediaList}; use crate::properties::ComputedValues; use crate::selector_parser::SnapshotMap; -use crate::shared_lock::{Locked, SharedRwLockReadGuard, StylesheetGuards}; +use crate::shared_lock::{SharedRwLockReadGuard, StylesheetGuards}; use crate::stylesheets::{StylesheetContents, StylesheetInDocument}; use crate::stylist::Stylist; use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut}; @@ -102,15 +101,12 @@ impl Clone for GeckoStyleSheet { impl StylesheetInDocument for GeckoStyleSheet { fn media<'a>(&'a self, guard: &'a SharedRwLockReadGuard) -> Option<&'a MediaList> { use crate::gecko_bindings::structs::mozilla::dom::MediaList as DomMediaList; - use std::mem; - unsafe { let dom_media_list = self.raw().mMedia.mRawPtr as *const DomMediaList; if dom_media_list.is_null() { return None; } - let raw_list = &*(*dom_media_list).mRawList.mRawPtr; - let list = Locked::::as_arc(mem::transmute(&raw_list)); + let list = &*(*dom_media_list).mRawList.mRawPtr; Some(list.read_with(guard)) } } diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index e085910bec0..3a1d61b019b 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -48,7 +48,6 @@ use crate::gecko_bindings::structs::NODE_DESCENDANTS_NEED_FRAMES; use crate::gecko_bindings::structs::NODE_NEEDS_FRAME; use crate::gecko_bindings::structs::{nsAtom, nsIContent, nsINode_BooleanFlag}; use crate::gecko_bindings::structs::{nsINode as RawGeckoNode, Element as RawGeckoElement}; -use crate::gecko_bindings::sugar::ownership::HasArcFFI; use crate::global_style_data::GLOBAL_STYLE_DATA; use crate::invalidation::element::restyle_hints::RestyleHint; use crate::media_queries::Device; @@ -75,7 +74,7 @@ use selectors::matching::VisitedHandlingMode; use selectors::matching::{ElementSelectorFlags, MatchingContext}; use selectors::sink::Push; use selectors::{Element, OpaqueElement}; -use servo_arc::{Arc, ArcBorrow, RawOffsetArc}; +use servo_arc::{Arc, ArcBorrow}; use std::fmt; use std::hash::{Hash, Hasher}; use std::mem; @@ -1139,10 +1138,10 @@ impl<'le> TElement for GeckoElement<'le> { return None; } - let declarations = unsafe { Gecko_GetStyleAttrDeclarationBlock(self.0).as_ref() }; - let declarations: Option<&RawOffsetArc>> = - declarations.and_then(|s| s.as_arc_opt()); - declarations.map(|s| s.borrow_arc()) + unsafe { + let declarations = Gecko_GetStyleAttrDeclarationBlock(self.0).as_ref()?; + Some(ArcBorrow::from_ref(declarations)) + } } fn unset_dirty_style_attribute(&self) { @@ -1160,14 +1159,8 @@ impl<'le> TElement for GeckoElement<'le> { let declaration: &structs::DeclarationBlock = slots.mSMILOverrideStyleDeclaration.mRawPtr.as_ref()?; - let raw: &structs::RawServoDeclarationBlock = declaration.mRaw.mRawPtr.as_ref()?; - - Some( - Locked::::as_arc( - &*(&raw as *const &structs::RawServoDeclarationBlock), - ) - .borrow_arc(), - ) + let raw: &structs::StyleLockedDeclarationBlock = declaration.mRaw.mRawPtr.as_ref()?; + Some(ArcBorrow::from_ref(raw)) } } @@ -1652,21 +1645,17 @@ impl<'le> TElement for GeckoElement<'le> { } let declarations = unsafe { Gecko_GetHTMLPresentationAttrDeclarationBlock(self.0).as_ref() }; - let declarations: Option<&RawOffsetArc>> = - declarations.and_then(|s| s.as_arc_opt()); if let Some(decl) = declarations { hints.push(ApplicableDeclarationBlock::from_declarations( - decl.clone_arc(), + unsafe { Arc::from_raw_addrefed(decl) }, ServoCascadeLevel::PresHints, LayerOrder::root(), )); } let declarations = unsafe { Gecko_GetExtraContentStyleDeclarations(self.0).as_ref() }; - let declarations: Option<&RawOffsetArc>> = - declarations.and_then(|s| s.as_arc_opt()); if let Some(decl) = declarations { hints.push(ApplicableDeclarationBlock::from_declarations( - decl.clone_arc(), + unsafe { Arc::from_raw_addrefed(decl) }, ServoCascadeLevel::PresHints, LayerOrder::root(), )); @@ -1690,11 +1679,9 @@ impl<'le> TElement for GeckoElement<'le> { Gecko_GetVisitedLinkAttrDeclarationBlock(self.0).as_ref() }, }; - let declarations: Option<&RawOffsetArc>> = - declarations.and_then(|s| s.as_arc_opt()); if let Some(decl) = declarations { hints.push(ApplicableDeclarationBlock::from_declarations( - decl.clone_arc(), + unsafe { Arc::from_raw_addrefed(decl) }, ServoCascadeLevel::PresHints, LayerOrder::root(), )); @@ -1706,11 +1693,9 @@ impl<'le> TElement for GeckoElement<'le> { if active { let declarations = unsafe { Gecko_GetActiveLinkAttrDeclarationBlock(self.0).as_ref() }; - let declarations: Option<&RawOffsetArc>> = - declarations.and_then(|s| s.as_arc_opt()); if let Some(decl) = declarations { hints.push(ApplicableDeclarationBlock::from_declarations( - decl.clone_arc(), + unsafe { Arc::from_raw_addrefed(decl) }, ServoCascadeLevel::PresHints, LayerOrder::root(), )); diff --git a/components/style/gecko_bindings/sugar/ownership.rs b/components/style/gecko_bindings/sugar/ownership.rs index cd965038704..31b512cf1e8 100644 --- a/components/style/gecko_bindings/sugar/ownership.rs +++ b/components/style/gecko_bindings/sugar/ownership.rs @@ -5,85 +5,11 @@ //! Helpers for different FFI pointer kinds that Gecko's FFI layer uses. use crate::gecko_bindings::structs::root::mozilla::detail::CopyablePtr; -use servo_arc::{Arc, RawOffsetArc}; +use servo_arc::Arc; use std::marker::PhantomData; -use std::mem::{forget, transmute}; use std::ops::{Deref, DerefMut}; use std::ptr; -/// Helper trait for conversions between FFI Strong/Borrowed types and Arcs -/// -/// Should be implemented by types which are passed over FFI as Arcs via Strong -/// and Borrowed. -/// -/// In this case, the FFIType is the rough equivalent of ArcInner. -pub unsafe trait HasArcFFI: Sized + 'static { - /// The corresponding Gecko type that this rust type represents. - /// - /// See the examples in `components/style/gecko/conversions.rs`. - type FFIType: Sized; - - // these methods can't be on Borrowed because it leads to an unspecified - // impl parameter - /// Artificially increments the refcount of a (possibly null) borrowed Arc - /// over FFI. - unsafe fn addref_opt(ptr: Option<&Self::FFIType>) { - forget(Self::arc_from_borrowed(&ptr).clone()) - } - - /// Given a (possibly null) borrowed FFI reference, decrements the refcount. - /// Unsafe since it doesn't consume the backing Arc. Run it only when you - /// know that a strong reference to the backing Arc is disappearing - /// (usually on the C++ side) without running the Arc destructor. - unsafe fn release_opt(ptr: Option<&Self::FFIType>) { - if let Some(arc) = Self::arc_from_borrowed(&ptr) { - let _: RawOffsetArc<_> = ptr::read(arc as *const RawOffsetArc<_>); - } - } - - /// Artificially increments the refcount of a borrowed Arc over FFI. - unsafe fn addref(ptr: &Self::FFIType) { - forget(Self::as_arc(&ptr).clone()) - } - - /// Given a non-null borrowed FFI reference, decrements the refcount. - /// Unsafe since it doesn't consume the backing Arc. Run it only when you - /// know that a strong reference to the backing Arc is disappearing - /// (usually on the C++ side) without running the Arc destructor. - unsafe fn release(ptr: &Self::FFIType) { - let _: RawOffsetArc<_> = ptr::read(Self::as_arc(&ptr) as *const RawOffsetArc<_>); - } - #[inline] - /// Converts a borrowed FFI reference to a borrowed Arc. - /// - /// &GeckoType -> &Arc - fn as_arc<'a>(ptr: &'a &Self::FFIType) -> &'a RawOffsetArc { - unsafe { transmute::<&&Self::FFIType, &RawOffsetArc>(ptr) } - } - - #[inline] - /// Converts a borrowed Arc to a borrowed FFI reference. - /// - /// &Arc -> &GeckoType - fn arc_as_borrowed<'a>(arc: &'a RawOffsetArc) -> &'a &Self::FFIType { - unsafe { transmute::<&RawOffsetArc, &&Self::FFIType>(arc) } - } - - #[inline] - /// Converts a borrowed nullable FFI reference to a borrowed Arc. - /// - /// &GeckoType -> &Arc - fn arc_from_borrowed<'a>(ptr: &'a Option<&Self::FFIType>) -> Option<&'a RawOffsetArc> { - unsafe { - if let Some(ref reference) = *ptr { - Some(transmute::<&&Self::FFIType, &RawOffsetArc<_>>(reference)) - } else { - None - } - } - } -} - /// Gecko-FFI-safe Arc (T is an ArcInner). /// /// This can be null. @@ -112,98 +38,12 @@ impl Strong { } #[inline] - /// Given a non-null strong FFI reference, converts it into a servo-side - /// Arc. - /// - /// Panics on null. - /// - /// Strong -> Arc - pub fn into_arc(self) -> RawOffsetArc - where - ServoType: HasArcFFI, - { - self.into_arc_opt().unwrap() - } - - #[inline] - /// Given a strong FFI reference, - /// converts it into a servo-side Arc - /// Returns None on null. - /// - /// Strong -> Arc - pub fn into_arc_opt(self) -> Option> - where - ServoType: HasArcFFI, - { - if self.is_null() { - None - } else { - unsafe { Some(transmute(self)) } - } - } - - #[inline] - /// Given a reference to a strong FFI reference, converts it to a reference - /// to a servo-side Arc. - /// - /// Returns None on null. - /// - /// Strong -> Arc - pub fn as_arc_opt(&self) -> Option<&RawOffsetArc> - where - ServoType: HasArcFFI, - { - if self.is_null() { - None - } else { - unsafe { Some(transmute(self)) } - } - } - - #[inline] - /// Produces a null strong FFI reference. + /// Returns a null pointer pub fn null() -> Self { - unsafe { transmute(ptr::null::()) } - } -} - -/// A few helpers implemented on top of Arc to make it more -/// comfortable to use and write safe code with. -pub unsafe trait FFIArcHelpers { - /// Converts an Arc into a strong FFI reference. - /// - /// Arc -> Strong - fn into_strong(self) -> Strong; - - /// Produces a borrowed FFI reference by borrowing an Arc. - /// - /// &Arc -> &GeckoType - /// - /// Then the `arc_as_borrowed` method can go away. - fn as_borrowed(&self) -> &T::FFIType; -} - -unsafe impl FFIArcHelpers for RawOffsetArc { - #[inline] - fn into_strong(self) -> Strong { - unsafe { transmute(self) } - } - - #[inline] - fn as_borrowed(&self) -> &T::FFIType { - unsafe { &*(&**self as *const T as *const T::FFIType) } - } -} - -unsafe impl FFIArcHelpers for Arc { - #[inline] - fn into_strong(self) -> Strong { - Arc::into_raw_offset(self).into_strong() - } - - #[inline] - fn as_borrowed(&self) -> &T::FFIType { - unsafe { &*(&**self as *const T as *const T::FFIType) } + Self { + ptr: ptr::null(), + _marker: PhantomData, + } } } diff --git a/components/style/gecko_bindings/sugar/refptr.rs b/components/style/gecko_bindings/sugar/refptr.rs index 51e2b095e66..c4a0479a077 100644 --- a/components/style/gecko_bindings/sugar/refptr.rs +++ b/components/style/gecko_bindings/sugar/refptr.rs @@ -4,14 +4,13 @@ //! A rust helper to ease the use of Gecko's refcounted types. -use crate::gecko_bindings::sugar::ownership::HasArcFFI; use crate::gecko_bindings::{bindings, structs}; use crate::Atom; use servo_arc::Arc; +use std::fmt::Write; use std::marker::PhantomData; use std::ops::Deref; use std::{fmt, mem, ptr}; -use std::fmt::Write; /// Trait for all objects that have Addref() and Release /// methods and can be placed inside RefPtr @@ -200,17 +199,6 @@ impl structs::RefPtr { } } - /// Create a new RefPtr from an arc. - pub fn from_arc_ffi(s: Arc) -> Self - where - U: HasArcFFI, - { - Self { - mRawPtr: unsafe { mem::transmute(Arc::into_raw_offset(s)) }, - _phantom_0: PhantomData, - } - } - /// Sets the contents to an Arc. pub fn set_arc(&mut self, other: Arc) { unsafe { @@ -220,17 +208,6 @@ impl structs::RefPtr { self.mRawPtr = Arc::into_raw(other) as *mut _; } } - - /// Sets the contents to an Arc. - pub fn set_arc_ffi(&mut self, other: Arc) - where - U: HasArcFFI, - { - unsafe { - U::release_opt(self.mRawPtr.as_ref()); - } - *self = unsafe { mem::transmute(Arc::into_raw_offset(other)) }; - } } impl Drop for RefPtr { diff --git a/components/style/stylesheets/rule_list.rs b/components/style/stylesheets/rule_list.rs index 196f8eaf62a..ab747565ffe 100644 --- a/components/style/stylesheets/rule_list.rs +++ b/components/style/stylesheets/rule_list.rs @@ -13,7 +13,7 @@ use crate::stylesheets::stylesheet::StylesheetContents; use crate::stylesheets::{AllowImportRules, CssRule, RulesMutateError}; #[cfg(feature = "gecko")] use malloc_size_of::{MallocShallowSizeOf, MallocSizeOfOps}; -use servo_arc::{Arc, RawOffsetArc}; +use servo_arc::Arc; use std::fmt::{self, Write}; /// A list of CSS rules. @@ -141,7 +141,7 @@ pub trait CssRulesHelpers { ) -> Result; } -impl CssRulesHelpers for RawOffsetArc> { +impl CssRulesHelpers for Locked { fn insert_rule( &self, lock: &SharedRwLock,