style: Finish removing HasArcFFI

Use the actual Locked<T> types around (via a typedef, just for
convenience).

Differential Revision: https://phabricator.services.mozilla.com/D177824
This commit is contained in:
Emilio Cobos Álvarez 2023-05-12 22:31:38 +00:00 committed by Martin Robinson
parent 3f03650c88
commit e9bf977369
6 changed files with 147 additions and 311 deletions

View file

@ -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<CssRules> => ServoCssRules
[Servo_CssRules_AddRef, Servo_CssRules_Release]);
impl_arc_ffi!(Locked<PropertyDeclarationBlock> => RawServoDeclarationBlock
[Servo_DeclarationBlock_AddRef, Servo_DeclarationBlock_Release]);
impl_arc_ffi!(Locked<StyleRule> => RawServoStyleRule
[Servo_StyleRule_AddRef, Servo_StyleRule_Release]);
impl_arc_ffi!(Locked<ImportRule> => RawServoImportRule
[Servo_ImportRule_AddRef, Servo_ImportRule_Release]);
impl_arc_ffi!(Locked<Keyframe> => RawServoKeyframe
[Servo_Keyframe_AddRef, Servo_Keyframe_Release]);
impl_arc_ffi!(Locked<KeyframesRule> => RawServoKeyframesRule
[Servo_KeyframesRule_AddRef, Servo_KeyframesRule_Release]);
impl_arc_ffi!(Locked<LayerBlockRule> => RawServoLayerBlockRule
[Servo_LayerBlockRule_AddRef, Servo_LayerBlockRule_Release]);
impl_arc_ffi!(Locked<LayerStatementRule> => RawServoLayerStatementRule
[Servo_LayerStatementRule_AddRef, Servo_LayerStatementRule_Release]);
impl_arc_ffi!(Locked<MediaList> => RawServoMediaList
[Servo_MediaList_AddRef, Servo_MediaList_Release]);
impl_arc_ffi!(Locked<MediaRule> => RawServoMediaRule
[Servo_MediaRule_AddRef, Servo_MediaRule_Release]);
impl_arc_ffi!(Locked<NamespaceRule> => RawServoNamespaceRule
[Servo_NamespaceRule_AddRef, Servo_NamespaceRule_Release]);
impl_arc_ffi!(Locked<PageRule> => RawServoPageRule
[Servo_PageRule_AddRef, Servo_PageRule_Release]);
impl_arc_ffi!(Locked<SupportsRule> => RawServoSupportsRule
[Servo_SupportsRule_AddRef, Servo_SupportsRule_Release]);
impl_arc_ffi!(Locked<ContainerRule> => RawServoContainerRule
[Servo_ContainerRule_AddRef, Servo_ContainerRule_Release]);
impl_arc_ffi!(Locked<DocumentRule> => RawServoMozDocumentRule
[Servo_DocumentRule_AddRef, Servo_DocumentRule_Release]);
impl_arc_ffi!(Locked<FontFeatureValuesRule> => RawServoFontFeatureValuesRule
[Servo_FontFeatureValuesRule_AddRef, Servo_FontFeatureValuesRule_Release]);
impl_arc_ffi!(Locked<FontPaletteValuesRule> => RawServoFontPaletteValuesRule
[Servo_FontPaletteValuesRule_AddRef, Servo_FontPaletteValuesRule_Release]);
impl_arc_ffi!(Locked<FontFaceRule> => RawServoFontFaceRule
[Servo_FontFaceRule_AddRef, Servo_FontFaceRule_Release]);
impl_arc_ffi!(Locked<CounterStyleRule> => 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,

View file

@ -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::<MediaList>::as_arc(mem::transmute(&raw_list));
let list = &*(*dom_media_list).mRawList.mRawPtr;
Some(list.read_with(guard))
}
}

View file

@ -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<Locked<PropertyDeclarationBlock>>> =
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::<PropertyDeclarationBlock>::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<Locked<PropertyDeclarationBlock>>> =
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<Locked<PropertyDeclarationBlock>>> =
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<Locked<PropertyDeclarationBlock>>> =
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<Locked<PropertyDeclarationBlock>>> =
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(),
));

View file

@ -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<Self>.
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<ServoType>
fn as_arc<'a>(ptr: &'a &Self::FFIType) -> &'a RawOffsetArc<Self> {
unsafe { transmute::<&&Self::FFIType, &RawOffsetArc<Self>>(ptr) }
}
#[inline]
/// Converts a borrowed Arc to a borrowed FFI reference.
///
/// &Arc<ServoType> -> &GeckoType
fn arc_as_borrowed<'a>(arc: &'a RawOffsetArc<Self>) -> &'a &Self::FFIType {
unsafe { transmute::<&RawOffsetArc<Self>, &&Self::FFIType>(arc) }
}
#[inline]
/// Converts a borrowed nullable FFI reference to a borrowed Arc.
///
/// &GeckoType -> &Arc<ServoType>
fn arc_from_borrowed<'a>(ptr: &'a Option<&Self::FFIType>) -> Option<&'a RawOffsetArc<Self>> {
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<GeckoType> Strong<GeckoType> {
}
#[inline]
/// Given a non-null strong FFI reference, converts it into a servo-side
/// Arc.
///
/// Panics on null.
///
/// Strong<GeckoType> -> Arc<ServoType>
pub fn into_arc<ServoType>(self) -> RawOffsetArc<ServoType>
where
ServoType: HasArcFFI<FFIType = GeckoType>,
{
self.into_arc_opt().unwrap()
}
#[inline]
/// Given a strong FFI reference,
/// converts it into a servo-side Arc
/// Returns None on null.
///
/// Strong<GeckoType> -> Arc<ServoType>
pub fn into_arc_opt<ServoType>(self) -> Option<RawOffsetArc<ServoType>>
where
ServoType: HasArcFFI<FFIType = GeckoType>,
{
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<GeckoType> -> Arc<ServoType>
pub fn as_arc_opt<ServoType>(&self) -> Option<&RawOffsetArc<ServoType>>
where
ServoType: HasArcFFI<FFIType = GeckoType>,
{
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::<GeckoType>()) }
}
}
/// A few helpers implemented on top of Arc<ServoType> to make it more
/// comfortable to use and write safe code with.
pub unsafe trait FFIArcHelpers<T: HasArcFFI> {
/// Converts an Arc into a strong FFI reference.
///
/// Arc<ServoType> -> Strong<GeckoType>
fn into_strong(self) -> Strong<T::FFIType>;
/// Produces a borrowed FFI reference by borrowing an Arc.
///
/// &Arc<ServoType> -> &GeckoType
///
/// Then the `arc_as_borrowed` method can go away.
fn as_borrowed(&self) -> &T::FFIType;
}
unsafe impl<T: HasArcFFI> FFIArcHelpers<T> for RawOffsetArc<T> {
#[inline]
fn into_strong(self) -> Strong<T::FFIType> {
unsafe { transmute(self) }
}
#[inline]
fn as_borrowed(&self) -> &T::FFIType {
unsafe { &*(&**self as *const T as *const T::FFIType) }
}
}
unsafe impl<T: HasArcFFI> FFIArcHelpers<T> for Arc<T> {
#[inline]
fn into_strong(self) -> Strong<T::FFIType> {
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,
}
}
}

View file

@ -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<T>
@ -200,17 +199,6 @@ impl<T> structs::RefPtr<T> {
}
}
/// Create a new RefPtr from an arc.
pub fn from_arc_ffi<U>(s: Arc<U>) -> Self
where
U: HasArcFFI<FFIType = T>,
{
Self {
mRawPtr: unsafe { mem::transmute(Arc::into_raw_offset(s)) },
_phantom_0: PhantomData,
}
}
/// Sets the contents to an Arc<T>.
pub fn set_arc(&mut self, other: Arc<T>) {
unsafe {
@ -220,17 +208,6 @@ impl<T> structs::RefPtr<T> {
self.mRawPtr = Arc::into_raw(other) as *mut _;
}
}
/// Sets the contents to an Arc<U>.
pub fn set_arc_ffi<U>(&mut self, other: Arc<U>)
where
U: HasArcFFI<FFIType = T>,
{
unsafe {
U::release_opt(self.mRawPtr.as_ref());
}
*self = unsafe { mem::transmute(Arc::into_raw_offset(other)) };
}
}
impl<T: RefCounted> Drop for RefPtr<T> {

View file

@ -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<CssRule, RulesMutateError>;
}
impl CssRulesHelpers for RawOffsetArc<Locked<CssRules>> {
impl CssRulesHelpers for Locked<CssRules> {
fn insert_rule(
&self,
lock: &SharedRwLock,