mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
style: Allow references to static C++ URLExtraData objects from Rust UrlExtraData.
Each user agent style sheet has a unique URLExtraData object containing its URL, but since they are refcounted objects, we can't share them easily across processes. Rather than adding support for copying them into a shared memory buffer like we will do with the Rust objects, here we just set up a static array of URLExtraData objects per UA style sheet. The array will be filled in in a later patch. Rust UrlExtraData objects, once they are transformed into their sharable form and copied into the shared memory buffer, will reference them by an index. Differential Revision: https://phabricator.services.mozilla.com/D17182
This commit is contained in:
parent
5ebc3f8dfa
commit
91586eea0e
1 changed files with 72 additions and 11 deletions
|
@ -23,6 +23,10 @@ mod stylesheet;
|
||||||
pub mod supports_rule;
|
pub mod supports_rule;
|
||||||
pub mod viewport_rule;
|
pub mod viewport_rule;
|
||||||
|
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
use crate::gecko_bindings::sugar::refptr::RefCounted;
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
use crate::gecko_bindings::{bindings, structs};
|
||||||
use crate::parser::ParserContext;
|
use crate::parser::ParserContext;
|
||||||
use crate::shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked};
|
use crate::shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked};
|
||||||
use crate::shared_lock::{SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
|
use crate::shared_lock::{SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
|
||||||
|
@ -32,6 +36,8 @@ use cssparser::{parse_one_rule, Parser, ParserInput};
|
||||||
use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
|
use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
use std::mem;
|
||||||
use style_traits::ParsingMode;
|
use style_traits::ParsingMode;
|
||||||
|
|
||||||
pub use self::counter_style_rule::CounterStyleRule;
|
pub use self::counter_style_rule::CounterStyleRule;
|
||||||
|
@ -60,18 +66,56 @@ pub use self::viewport_rule::ViewportRule;
|
||||||
pub type UrlExtraData = ::servo_url::ServoUrl;
|
pub type UrlExtraData = ::servo_url::ServoUrl;
|
||||||
|
|
||||||
/// Extra data that the backend may need to resolve url values.
|
/// Extra data that the backend may need to resolve url values.
|
||||||
|
///
|
||||||
|
/// If the usize's lowest bit is 0, then this is a strong reference to a
|
||||||
|
/// structs::URLExtraData object.
|
||||||
|
///
|
||||||
|
/// Otherwise, shifting the usize's bits the right by one gives the
|
||||||
|
/// UserAgentStyleSheetID value corresponding to the style sheet whose
|
||||||
|
/// URLExtraData this is, which is stored in URLExtraData_sShared. We don't
|
||||||
|
/// hold a strong reference to that object from here, but we rely on that
|
||||||
|
/// array's objects being held alive until shutdown.
|
||||||
|
///
|
||||||
|
/// We use this packed representation rather than an enum so that
|
||||||
|
/// `from_ptr_ref` can work.
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(PartialEq)]
|
||||||
pub struct UrlExtraData(
|
pub struct UrlExtraData(usize);
|
||||||
pub crate::gecko_bindings::sugar::refptr::RefPtr<crate::gecko_bindings::structs::URLExtraData>,
|
|
||||||
);
|
#[cfg(feature = "gecko")]
|
||||||
|
impl Clone for UrlExtraData {
|
||||||
|
fn clone(&self) -> UrlExtraData {
|
||||||
|
UrlExtraData::new(self.ptr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
impl Drop for UrlExtraData {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
// No need to release when we have an index into URLExtraData_sShared.
|
||||||
|
if self.0 & 1 == 0 {
|
||||||
|
unsafe {
|
||||||
|
self.as_ref().release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
impl UrlExtraData {
|
impl UrlExtraData {
|
||||||
|
/// Create a new UrlExtraData wrapping a pointer to the specified Gecko
|
||||||
|
/// URLExtraData object.
|
||||||
|
pub fn new(ptr: *mut structs::URLExtraData) -> UrlExtraData {
|
||||||
|
unsafe {
|
||||||
|
(*ptr).addref();
|
||||||
|
}
|
||||||
|
UrlExtraData(ptr as usize)
|
||||||
|
}
|
||||||
|
|
||||||
/// True if this URL scheme is chrome.
|
/// True if this URL scheme is chrome.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_chrome(&self) -> bool {
|
pub fn is_chrome(&self) -> bool {
|
||||||
self.0.mIsChrome
|
self.as_ref().mIsChrome
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a reference to this `UrlExtraData` from a reference to pointer.
|
/// Create a reference to this `UrlExtraData` from a reference to pointer.
|
||||||
|
@ -80,16 +124,30 @@ impl UrlExtraData {
|
||||||
///
|
///
|
||||||
/// This method doesn't touch refcount.
|
/// This method doesn't touch refcount.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_ptr_ref(ptr: &*mut crate::gecko_bindings::structs::URLExtraData) -> &Self {
|
pub unsafe fn from_ptr_ref(ptr: &*mut structs::URLExtraData) -> &Self {
|
||||||
::std::mem::transmute(ptr)
|
mem::transmute(ptr)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a pointer to the Gecko URLExtraData object.
|
||||||
|
pub fn ptr(&self) -> *mut structs::URLExtraData {
|
||||||
|
if self.0 & 1 == 0 {
|
||||||
|
self.0 as *mut structs::URLExtraData
|
||||||
|
} else {
|
||||||
|
unsafe {
|
||||||
|
let sheet_id = self.0 >> 1;
|
||||||
|
structs::URLExtraData_sShared[sheet_id].mRawPtr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_ref(&self) -> &structs::URLExtraData {
|
||||||
|
unsafe { &*(self.ptr() as *const structs::URLExtraData) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
impl fmt::Debug for UrlExtraData {
|
impl fmt::Debug for UrlExtraData {
|
||||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
use crate::gecko_bindings::{bindings, structs};
|
|
||||||
|
|
||||||
struct DebugURI(*mut structs::nsIURI);
|
struct DebugURI(*mut structs::nsIURI);
|
||||||
impl fmt::Debug for DebugURI {
|
impl fmt::Debug for DebugURI {
|
||||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
@ -105,10 +163,13 @@ impl fmt::Debug for UrlExtraData {
|
||||||
formatter
|
formatter
|
||||||
.debug_struct("URLExtraData")
|
.debug_struct("URLExtraData")
|
||||||
.field("is_chrome", &self.is_chrome())
|
.field("is_chrome", &self.is_chrome())
|
||||||
.field("base", &DebugURI(self.0.mBaseURI.raw::<structs::nsIURI>()))
|
.field(
|
||||||
|
"base",
|
||||||
|
&DebugURI(self.as_ref().mBaseURI.raw::<structs::nsIURI>()),
|
||||||
|
)
|
||||||
.field(
|
.field(
|
||||||
"referrer",
|
"referrer",
|
||||||
&DebugURI(self.0.mReferrer.raw::<structs::nsIURI>()),
|
&DebugURI(self.as_ref().mReferrer.raw::<structs::nsIURI>()),
|
||||||
)
|
)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue