auto merge of #3574 : saneyuki/servo/cell, r=jdm

#3050
This commit is contained in:
bors-servo 2014-10-14 23:12:24 -06:00
commit 7c1054e6ab
6 changed files with 94 additions and 33 deletions

View file

@ -35,6 +35,7 @@ use css::node_style::StyledNode;
use util::{LayoutDataAccess, LayoutDataWrapper, PrivateLayoutData, OpaqueNodeMethods};
use gfx::display_list::OpaqueNode;
use script::dom::bindings::cell::{Ref, RefMut};
use script::dom::bindings::codegen::InheritTypes::{ElementCast, HTMLIFrameElementCast, HTMLImageElementCast};
use script::dom::bindings::codegen::InheritTypes::{HTMLInputElementCast, TextCast};
use script::dom::bindings::js::JS;
@ -50,7 +51,6 @@ use script::dom::text::Text;
use script::layout_interface::LayoutChan;
use servo_msg::constellation_msg::{PipelineId, SubpageId};
use servo_util::str::{LengthOrPercentageOrAuto, is_whitespace};
use std::cell::{RefCell, Ref, RefMut};
use std::kinds::marker::ContravariantLifetime;
use std::mem;
use style::computed_values::{content, display, white_space};
@ -445,9 +445,7 @@ pub struct LayoutElement<'le> {
impl<'le> LayoutElement<'le> {
pub fn style_attribute(&self) -> &'le Option<PropertyDeclarationBlock> {
let style: &Option<PropertyDeclarationBlock> = unsafe {
let style: &RefCell<Option<PropertyDeclarationBlock>> = self.element.style_attribute();
// cast to the direct reference to T placed on the head of RefCell<T>
mem::transmute(style)
&*self.element.style_attribute().borrow_for_layout()
};
style
}

View file

@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::cell::{DOMRefCell, Ref};
use dom::bindings::codegen::Bindings::AttrBinding;
use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
use dom::bindings::codegen::InheritTypes::NodeCast;
@ -15,7 +16,6 @@ use dom::virtualmethods::vtable_for;
use devtools_traits::AttrInfo;
use servo_util::str::{DOMString, split_html_space_chars};
use std::cell::{Ref, RefCell};
use std::mem;
use string_cache::{Atom, Namespace};
@ -75,7 +75,7 @@ impl Str for AttrValue {
pub struct Attr {
reflector_: Reflector,
local_name: Atom,
value: RefCell<AttrValue>,
value: DOMRefCell<AttrValue>,
name: Atom,
namespace: Namespace,
prefix: Option<DOMString>,
@ -97,7 +97,7 @@ impl Attr {
Attr {
reflector_: Reflector::new(),
local_name: local_name,
value: RefCell::new(value),
value: DOMRefCell::new(value),
name: name,
namespace: namespace,
prefix: prefix,
@ -221,15 +221,14 @@ pub trait AttrHelpersForLayout {
impl AttrHelpersForLayout for Attr {
#[inline]
unsafe fn value_ref_forever(&self) -> &'static str {
// cast to point to T in RefCell<T> directly
let value = mem::transmute::<&RefCell<AttrValue>, &AttrValue>(&self.value);
// This transmute is used to cheat the lifetime restriction.
let value = mem::transmute::<&AttrValue, &AttrValue>(self.value.borrow_for_layout());
value.as_slice()
}
#[inline]
unsafe fn value_atom_forever(&self) -> Option<Atom> {
// cast to point to T in RefCell<T> directly
let value = mem::transmute::<&RefCell<AttrValue>, &AttrValue>(&self.value);
let value = self.value.borrow_for_layout();
match *value {
AtomAttrValue(ref val) => Some(val.clone()),
_ => None,
@ -238,8 +237,8 @@ impl AttrHelpersForLayout for Attr {
#[inline]
unsafe fn value_tokens_forever(&self) -> Option<&'static [Atom]> {
// cast to point to T in RefCell<T> directly
let value = mem::transmute::<&RefCell<AttrValue>, &AttrValue>(&self.value);
// This transmute is used to cheat the lifetime restriction.
let value = mem::transmute::<&AttrValue, &AttrValue>(self.value.borrow_for_layout());
match *value {
TokenListAttrValue(_, ref tokens) => Some(tokens.as_slice()),
_ => None,

View file

@ -0,0 +1,68 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::trace::JSTraceable;
use js::jsapi::{JSTracer};
use std::cell;
use std::cell::RefCell;
use std::mem;
/// A mutable field in DOM for large sized value.
/// This has a special method to return the pointer of itself
/// for used in layout task.
/// This simply wraps `RefCell<T>` to add the special method.
pub struct DOMRefCell<T> {
base: RefCell<T>,
}
pub type Ref<'a, T> = cell::Ref<'a, T>;
pub type RefMut<'a, T> = cell::RefMut<'a, T>;
impl<T> DOMRefCell<T> {
#[inline(always)]
pub fn new(value: T) -> DOMRefCell<T> {
DOMRefCell {
base: RefCell::new(value),
}
}
#[inline(always)]
pub fn unwrap(self) -> T {
self.base.unwrap()
}
#[inline(always)]
pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
self.base.try_borrow()
}
#[inline(always)]
pub fn borrow<'a>(&'a self) -> Ref<'a, T> {
self.base.borrow()
}
#[inline(always)]
pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> {
self.base.try_borrow_mut()
}
#[inline(always)]
pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> {
self.base.borrow_mut()
}
/// This returns the pointer which refers T in `RefCell<T>` directly.
pub unsafe fn borrow_for_layout<'a>(&'a self) -> &'a T {
let val = mem::transmute::<&RefCell<T>, &T>(&self.base);
val
}
}
impl<T: JSTraceable> JSTraceable for DOMRefCell<T> {
fn trace(&self, trc: *mut JSTracer) {
(*self).base.borrow().trace(trc)
}
}

View file

@ -4,6 +4,7 @@
//! DOM bindings for `CharacterData`.
use dom::bindings::cell::{DOMRefCell, Ref};
use dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods;
use dom::bindings::codegen::InheritTypes::{CharacterDataDerived, NodeCast};
use dom::bindings::error::{Fallible, ErrorResult, IndexSize};
@ -14,15 +15,12 @@ use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::node::{CommentNodeTypeId, Node, NodeTypeId, TextNodeTypeId, ProcessingInstructionNodeTypeId, NodeHelpers};
use servo_util::str::DOMString;
use std::cell::{Ref, RefCell};
use std::mem;
#[jstraceable]
#[must_root]
#[privatize]
pub struct CharacterData {
node: Node,
data: RefCell<DOMString>,
data: DOMRefCell<DOMString>,
}
impl CharacterDataDerived for EventTarget {
@ -40,7 +38,7 @@ impl CharacterData {
pub fn new_inherited(id: NodeTypeId, data: DOMString, document: JSRef<Document>) -> CharacterData {
CharacterData {
node: Node::new_inherited(id, document),
data: RefCell::new(data),
data: DOMRefCell::new(data),
}
}
@ -61,7 +59,7 @@ impl CharacterData {
#[inline]
pub unsafe fn data_for_layout<'a>(&'a self) -> &'a str {
mem::transmute::<&RefCell<DOMString>, &DOMString>(&self.data).as_slice()
self.data.borrow_for_layout().as_slice()
}
}

View file

@ -7,6 +7,7 @@
use dom::attr::{Attr, ReplacedAttr, FirstSetAttr, AttrHelpers, AttrHelpersForLayout};
use dom::attr::{AttrValue, StringAttrValue, UIntAttrValue, AtomAttrValue};
use dom::namednodemap::NamedNodeMap;
use dom::bindings::cell::{DOMRefCell, Ref, RefMut};
use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
use dom::bindings::codegen::Bindings::ElementBinding;
use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods;
@ -39,7 +40,6 @@ use servo_util::namespace;
use servo_util::str::{DOMString, LengthOrPercentageOrAuto};
use std::ascii::StrAsciiExt;
use std::cell::{Ref, RefMut, RefCell};
use std::default::Default;
use std::mem;
use string_cache::{Atom, Namespace};
@ -53,8 +53,8 @@ pub struct Element {
local_name: Atom,
namespace: Namespace,
prefix: Option<DOMString>,
attrs: RefCell<Vec<JS<Attr>>>,
style_attribute: RefCell<Option<style::PropertyDeclarationBlock>>,
attrs: DOMRefCell<Vec<JS<Attr>>>,
style_attribute: DOMRefCell<Option<style::PropertyDeclarationBlock>>,
attr_list: MutNullableJS<NamedNodeMap>,
class_list: MutNullableJS<DOMTokenList>,
}
@ -160,10 +160,10 @@ impl Element {
local_name: Atom::from_slice(local_name.as_slice()),
namespace: namespace,
prefix: prefix,
attrs: RefCell::new(vec!()),
attrs: DOMRefCell::new(vec!()),
attr_list: Default::default(),
class_list: Default::default(),
style_attribute: RefCell::new(None),
style_attribute: DOMRefCell::new(None),
}
}
@ -203,7 +203,7 @@ impl Element {
}
#[inline]
pub fn style_attribute<'a>(&'a self) -> &'a RefCell<Option<style::PropertyDeclarationBlock>> {
pub fn style_attribute<'a>(&'a self) -> &'a DOMRefCell<Option<style::PropertyDeclarationBlock>> {
&self.style_attribute
}
}
@ -226,8 +226,7 @@ impl RawLayoutElementHelpers for Element {
#[allow(unrooted_must_root)]
unsafe fn get_attr_val_for_layout<'a>(&'a self, namespace: &Namespace, name: &Atom)
-> Option<&'a str> {
// cast to point to T in RefCell<T> directly
let attrs: *const Vec<JS<Attr>> = mem::transmute(&self.attrs);
let attrs = self.attrs.borrow_for_layout();
(*attrs).iter().find(|attr: & &JS<Attr>| {
let attr = attr.unsafe_get();
*name == (*attr).local_name_atom_forever() &&
@ -241,8 +240,7 @@ impl RawLayoutElementHelpers for Element {
#[inline]
#[allow(unrooted_must_root)]
unsafe fn get_attr_vals_for_layout<'a>(&'a self, name: &Atom) -> Vec<&'a str> {
// cast to point to T in RefCell<T> directly
let attrs: *const Vec<JS<Attr>> = mem::transmute(&self.attrs);
let attrs = self.attrs.borrow_for_layout();
(*attrs).iter().filter_map(|attr: &JS<Attr>| {
let attr = attr.unsafe_get();
if *name == (*attr).local_name_atom_forever() {
@ -257,8 +255,7 @@ impl RawLayoutElementHelpers for Element {
#[allow(unrooted_must_root)]
unsafe fn get_attr_atom_for_layout(&self, namespace: &Namespace, name: &Atom)
-> Option<Atom> {
// cast to point to T in RefCell<T> directly
let attrs: *const Vec<JS<Attr>> = mem::transmute(&self.attrs);
let attrs = self.attrs.borrow_for_layout();
(*attrs).iter().find(|attr: & &JS<Attr>| {
let attr = attr.unsafe_get();
*name == (*attr).local_name_atom_forever() &&
@ -272,7 +269,7 @@ impl RawLayoutElementHelpers for Element {
#[inline]
#[allow(unrooted_must_root)]
unsafe fn has_class_for_layout(&self, name: &Atom) -> bool {
let attrs: *const Vec<JS<Attr>> = mem::transmute(&self.attrs);
let attrs = self.attrs.borrow_for_layout();
(*attrs).iter().find(|attr: & &JS<Attr>| {
let attr = attr.unsafe_get();
(*attr).local_name_atom_forever() == atom!("class")
@ -287,7 +284,7 @@ impl RawLayoutElementHelpers for Element {
#[inline]
#[allow(unrooted_must_root)]
unsafe fn get_classes_for_layout(&self) -> Option<&'static [Atom]> {
let attrs: *const Vec<JS<Attr>> = mem::transmute(&self.attrs);
let attrs = self.attrs.borrow_for_layout();
(*attrs).iter().find(|attr: & &JS<Attr>| {
let attr = attr.unsafe_get();
(*attr).local_name_atom_forever() == atom!("class")

View file

@ -56,6 +56,7 @@ pub mod dom {
/// The code to expose the DOM to JavaScript through IDL bindings.
pub mod bindings {
pub mod cell;
pub mod global;
pub mod js;
pub mod utils;