mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +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 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::shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked};
|
||||
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 servo_arc::Arc;
|
||||
use std::fmt;
|
||||
#[cfg(feature = "gecko")]
|
||||
use std::mem;
|
||||
use style_traits::ParsingMode;
|
||||
|
||||
pub use self::counter_style_rule::CounterStyleRule;
|
||||
|
@ -60,18 +66,56 @@ pub use self::viewport_rule::ViewportRule;
|
|||
pub type UrlExtraData = ::servo_url::ServoUrl;
|
||||
|
||||
/// 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")]
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct UrlExtraData(
|
||||
pub crate::gecko_bindings::sugar::refptr::RefPtr<crate::gecko_bindings::structs::URLExtraData>,
|
||||
);
|
||||
#[derive(PartialEq)]
|
||||
pub struct UrlExtraData(usize);
|
||||
|
||||
#[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")]
|
||||
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.
|
||||
#[inline]
|
||||
pub fn is_chrome(&self) -> bool {
|
||||
self.0.mIsChrome
|
||||
self.as_ref().mIsChrome
|
||||
}
|
||||
|
||||
/// Create a reference to this `UrlExtraData` from a reference to pointer.
|
||||
|
@ -80,16 +124,30 @@ impl UrlExtraData {
|
|||
///
|
||||
/// This method doesn't touch refcount.
|
||||
#[inline]
|
||||
pub unsafe fn from_ptr_ref(ptr: &*mut crate::gecko_bindings::structs::URLExtraData) -> &Self {
|
||||
::std::mem::transmute(ptr)
|
||||
pub unsafe fn from_ptr_ref(ptr: &*mut structs::URLExtraData) -> &Self {
|
||||
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")]
|
||||
impl fmt::Debug for UrlExtraData {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
use crate::gecko_bindings::{bindings, structs};
|
||||
|
||||
struct DebugURI(*mut structs::nsIURI);
|
||||
impl fmt::Debug for DebugURI {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
|
@ -105,10 +163,13 @@ impl fmt::Debug for UrlExtraData {
|
|||
formatter
|
||||
.debug_struct("URLExtraData")
|
||||
.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(
|
||||
"referrer",
|
||||
&DebugURI(self.0.mReferrer.raw::<structs::nsIURI>()),
|
||||
&DebugURI(self.as_ref().mReferrer.raw::<structs::nsIURI>()),
|
||||
)
|
||||
.finish()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue