mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Make GeckoDeclarationBlock refcounted.
This commit is contained in:
parent
7aa0071e9b
commit
2f4d6b5ce1
4 changed files with 61 additions and 32 deletions
|
@ -148,7 +148,10 @@ COMPILATION_TARGETS = {
|
||||||
"void_types": [
|
"void_types": [
|
||||||
"nsINode", "nsIDocument", "nsIPrincipal", "nsIURI",
|
"nsINode", "nsIDocument", "nsIPrincipal", "nsIURI",
|
||||||
],
|
],
|
||||||
"servo_arc_types": ["ServoComputedValues", "RawServoStyleSheet"]
|
"servo_arc_types": [
|
||||||
|
"ServoComputedValues", "RawServoStyleSheet",
|
||||||
|
"ServoDeclarationBlock"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
"atoms": {
|
"atoms": {
|
||||||
|
|
|
@ -9,6 +9,8 @@ pub type ServoComputedValuesStrong = ::sugar::refptr::Strong<ServoComputedValues
|
||||||
pub type ServoComputedValuesBorrowed<'a> = ::sugar::refptr::Borrowed<'a, ServoComputedValues>;
|
pub type ServoComputedValuesBorrowed<'a> = ::sugar::refptr::Borrowed<'a, ServoComputedValues>;
|
||||||
pub type RawServoStyleSheetStrong = ::sugar::refptr::Strong<RawServoStyleSheet>;
|
pub type RawServoStyleSheetStrong = ::sugar::refptr::Strong<RawServoStyleSheet>;
|
||||||
pub type RawServoStyleSheetBorrowed<'a> = ::sugar::refptr::Borrowed<'a, RawServoStyleSheet>;
|
pub type RawServoStyleSheetBorrowed<'a> = ::sugar::refptr::Borrowed<'a, RawServoStyleSheet>;
|
||||||
|
pub type ServoDeclarationBlockStrong = ::sugar::refptr::Strong<ServoDeclarationBlock>;
|
||||||
|
pub type ServoDeclarationBlockBorrowed<'a> = ::sugar::refptr::Borrowed<'a, ServoDeclarationBlock>;
|
||||||
use structs::nsStyleFont;
|
use structs::nsStyleFont;
|
||||||
unsafe impl Send for nsStyleFont {}
|
unsafe impl Send for nsStyleFont {}
|
||||||
unsafe impl Sync for nsStyleFont {}
|
unsafe impl Sync for nsStyleFont {}
|
||||||
|
@ -254,7 +256,7 @@ extern "C" {
|
||||||
classList: *mut *mut *mut nsIAtom)
|
classList: *mut *mut *mut nsIAtom)
|
||||||
-> u32;
|
-> u32;
|
||||||
pub fn Gecko_GetServoDeclarationBlock(element: *mut RawGeckoElement)
|
pub fn Gecko_GetServoDeclarationBlock(element: *mut RawGeckoElement)
|
||||||
-> *mut ServoDeclarationBlock;
|
-> ServoDeclarationBlockBorrowed;
|
||||||
pub fn Gecko_GetNodeData(node: *mut RawGeckoNode) -> *mut ServoNodeData;
|
pub fn Gecko_GetNodeData(node: *mut RawGeckoNode) -> *mut ServoNodeData;
|
||||||
pub fn Gecko_SetNodeData(node: *mut RawGeckoNode,
|
pub fn Gecko_SetNodeData(node: *mut RawGeckoNode,
|
||||||
data: *mut ServoNodeData);
|
data: *mut ServoNodeData);
|
||||||
|
@ -467,16 +469,18 @@ extern "C" {
|
||||||
pub fn Servo_DropStyleSet(set: *mut RawServoStyleSet);
|
pub fn Servo_DropStyleSet(set: *mut RawServoStyleSet);
|
||||||
pub fn Servo_ParseStyleAttribute(bytes: *const u8, length: u32,
|
pub fn Servo_ParseStyleAttribute(bytes: *const u8, length: u32,
|
||||||
cache: *mut nsHTMLCSSStyleSheet)
|
cache: *mut nsHTMLCSSStyleSheet)
|
||||||
-> *mut ServoDeclarationBlock;
|
-> ServoDeclarationBlockStrong;
|
||||||
pub fn Servo_DropDeclarationBlock(declarations:
|
pub fn Servo_DeclarationBlock_AddRef(declarations:
|
||||||
*mut ServoDeclarationBlock);
|
ServoDeclarationBlockBorrowed);
|
||||||
|
pub fn Servo_DeclarationBlock_Release(declarations:
|
||||||
|
ServoDeclarationBlockBorrowed);
|
||||||
pub fn Servo_GetDeclarationBlockCache(declarations:
|
pub fn Servo_GetDeclarationBlockCache(declarations:
|
||||||
*mut ServoDeclarationBlock)
|
ServoDeclarationBlockBorrowed)
|
||||||
-> *mut nsHTMLCSSStyleSheet;
|
-> *mut nsHTMLCSSStyleSheet;
|
||||||
pub fn Servo_SetDeclarationBlockImmutable(declarations:
|
pub fn Servo_SetDeclarationBlockImmutable(declarations:
|
||||||
*mut ServoDeclarationBlock);
|
ServoDeclarationBlockBorrowed);
|
||||||
pub fn Servo_ClearDeclarationBlockCachePointer(declarations:
|
pub fn Servo_ClearDeclarationBlockCachePointer(declarations:
|
||||||
*mut ServoDeclarationBlock);
|
ServoDeclarationBlockBorrowed);
|
||||||
pub fn Servo_CSSSupports(name: *const u8, name_length: u32,
|
pub fn Servo_CSSSupports(name: *const u8, name_length: u32,
|
||||||
value: *const u8, value_length: u32) -> bool;
|
value: *const u8, value_length: u32) -> bool;
|
||||||
pub fn Servo_GetComputedValues(node: *mut RawGeckoNode)
|
pub fn Servo_GetComputedValues(node: *mut RawGeckoNode)
|
||||||
|
|
|
@ -13,6 +13,7 @@ use gecko_bindings::bindings::{RawGeckoDocument, RawGeckoElement, RawGeckoNode};
|
||||||
use gecko_bindings::bindings::{RawServoStyleSheetBorrowed, ServoComputedValuesBorrowed};
|
use gecko_bindings::bindings::{RawServoStyleSheetBorrowed, ServoComputedValuesBorrowed};
|
||||||
use gecko_bindings::bindings::{RawServoStyleSheetStrong, ServoComputedValuesStrong};
|
use gecko_bindings::bindings::{RawServoStyleSheetStrong, ServoComputedValuesStrong};
|
||||||
use gecko_bindings::bindings::{ServoDeclarationBlock, ServoNodeData, ThreadSafePrincipalHolder};
|
use gecko_bindings::bindings::{ServoDeclarationBlock, ServoNodeData, ThreadSafePrincipalHolder};
|
||||||
|
use gecko_bindings::bindings::{ServoDeclarationBlockBorrowed, ServoDeclarationBlockStrong};
|
||||||
use gecko_bindings::bindings::{ThreadSafeURIHolder, nsHTMLCSSStyleSheet};
|
use gecko_bindings::bindings::{ThreadSafeURIHolder, nsHTMLCSSStyleSheet};
|
||||||
use gecko_bindings::ptr::{GeckoArcPrincipal, GeckoArcURI};
|
use gecko_bindings::ptr::{GeckoArcPrincipal, GeckoArcURI};
|
||||||
use gecko_bindings::structs::ServoElementSnapshot;
|
use gecko_bindings::structs::ServoElementSnapshot;
|
||||||
|
@ -25,6 +26,7 @@ use std::mem::transmute;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::str::from_utf8_unchecked;
|
use std::str::from_utf8_unchecked;
|
||||||
|
use std::sync::atomic::{AtomicBool, AtomicPtr, Ordering};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use style::arc_ptr_eq;
|
use style::arc_ptr_eq;
|
||||||
use style::context::{LocalStyleContextCreationInfo, ReflowGoal, SharedStyleContext};
|
use style::context::{LocalStyleContextCreationInfo, ReflowGoal, SharedStyleContext};
|
||||||
|
@ -355,47 +357,62 @@ pub extern "C" fn Servo_DropStyleSet(data: *mut RawServoStyleSet) -> () {
|
||||||
|
|
||||||
pub struct GeckoDeclarationBlock {
|
pub struct GeckoDeclarationBlock {
|
||||||
pub declarations: Option<PropertyDeclarationBlock>,
|
pub declarations: Option<PropertyDeclarationBlock>,
|
||||||
pub cache: *mut nsHTMLCSSStyleSheet,
|
// XXX The following two fields are made atomic to work around the
|
||||||
pub immutable: bool,
|
// ownership system so that they can be changed inside a shared
|
||||||
|
// instance. It wouldn't provide safety as Rust usually promises,
|
||||||
|
// but it is fine as far as we only access them in a single thread.
|
||||||
|
// If we need to access them in different threads, we would need
|
||||||
|
// to redesign how it works with MiscContainer in Gecko side.
|
||||||
|
pub cache: AtomicPtr<nsHTMLCSSStyleSheet>,
|
||||||
|
pub immutable: AtomicBool,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl HasArcFFI for GeckoDeclarationBlock {
|
||||||
|
type FFIType = ServoDeclarationBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn Servo_ParseStyleAttribute(bytes: *const u8, length: u32,
|
pub extern "C" fn Servo_ParseStyleAttribute(bytes: *const u8, length: u32,
|
||||||
cache: *mut nsHTMLCSSStyleSheet)
|
cache: *mut nsHTMLCSSStyleSheet)
|
||||||
-> *mut ServoDeclarationBlock {
|
-> ServoDeclarationBlockStrong {
|
||||||
let value = unsafe { from_utf8_unchecked(slice::from_raw_parts(bytes, length as usize)) };
|
let value = unsafe { from_utf8_unchecked(slice::from_raw_parts(bytes, length as usize)) };
|
||||||
let declarations = Box::new(GeckoDeclarationBlock {
|
GeckoDeclarationBlock::from_arc(Arc::new(GeckoDeclarationBlock {
|
||||||
declarations: GeckoElement::parse_style_attribute(value),
|
declarations: GeckoElement::parse_style_attribute(value),
|
||||||
cache: cache,
|
cache: AtomicPtr::new(cache),
|
||||||
immutable: false,
|
immutable: AtomicBool::new(false),
|
||||||
});
|
}))
|
||||||
Box::into_raw(declarations) as *mut ServoDeclarationBlock
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn Servo_DropDeclarationBlock(declarations: *mut ServoDeclarationBlock) {
|
pub extern "C" fn Servo_DeclarationBlock_AddRef(declarations: ServoDeclarationBlockBorrowed) {
|
||||||
unsafe {
|
unsafe { GeckoDeclarationBlock::addref(declarations) };
|
||||||
let _ = Box::<GeckoDeclarationBlock>::from_raw(declarations as *mut GeckoDeclarationBlock);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn Servo_GetDeclarationBlockCache(declarations: *mut ServoDeclarationBlock)
|
pub extern "C" fn Servo_DeclarationBlock_Release(declarations: ServoDeclarationBlockBorrowed) {
|
||||||
|
unsafe { GeckoDeclarationBlock::release(declarations) };
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn Servo_GetDeclarationBlockCache(declarations: ServoDeclarationBlockBorrowed)
|
||||||
-> *mut nsHTMLCSSStyleSheet {
|
-> *mut nsHTMLCSSStyleSheet {
|
||||||
let declarations = unsafe { (declarations as *const GeckoDeclarationBlock).as_ref().unwrap() };
|
GeckoDeclarationBlock::with(declarations, |declarations| {
|
||||||
declarations.cache
|
declarations.cache.load(Ordering::Relaxed)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn Servo_SetDeclarationBlockImmutable(declarations: *mut ServoDeclarationBlock) {
|
pub extern "C" fn Servo_SetDeclarationBlockImmutable(declarations: ServoDeclarationBlockBorrowed) {
|
||||||
let declarations = unsafe { (declarations as *mut GeckoDeclarationBlock).as_mut().unwrap() };
|
GeckoDeclarationBlock::with(declarations, |declarations| {
|
||||||
declarations.immutable = true;
|
declarations.immutable.store(true, Ordering::Relaxed)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn Servo_ClearDeclarationBlockCachePointer(declarations: *mut ServoDeclarationBlock) {
|
pub extern "C" fn Servo_ClearDeclarationBlockCachePointer(declarations: ServoDeclarationBlockBorrowed) {
|
||||||
let declarations = unsafe { (declarations as *mut GeckoDeclarationBlock).as_mut().unwrap() };
|
GeckoDeclarationBlock::with(declarations, |declarations| {
|
||||||
declarations.cache = ptr::null_mut();
|
declarations.cache.store(ptr::null_mut(), Ordering::Relaxed)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|
|
@ -35,6 +35,7 @@ use snapshot::GeckoElementSnapshot;
|
||||||
use snapshot_helpers;
|
use snapshot_helpers;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
use std::mem::transmute;
|
||||||
use std::ops::BitOr;
|
use std::ops::BitOr;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -432,9 +433,13 @@ impl<'le> TElement for GeckoElement<'le> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn style_attribute(&self) -> &Option<PropertyDeclarationBlock> {
|
fn style_attribute(&self) -> &Option<PropertyDeclarationBlock> {
|
||||||
unsafe {
|
let declarations = unsafe { Gecko_GetServoDeclarationBlock(self.element) };
|
||||||
let ptr = Gecko_GetServoDeclarationBlock(self.element) as *mut GeckoDeclarationBlock;
|
if declarations.is_null() {
|
||||||
ptr.as_ref().map(|d| &d.declarations).unwrap_or(&NO_STYLE_ATTRIBUTE)
|
&NO_STYLE_ATTRIBUTE
|
||||||
|
} else {
|
||||||
|
GeckoDeclarationBlock::with(declarations, |declarations| {
|
||||||
|
unsafe { transmute(&declarations.declarations) }
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue