Skip to content

Commit

Permalink
auto merge of #3574 : saneyuki/servo/cell, r=jdm
Browse files Browse the repository at this point in the history
  • Loading branch information
bors-servo committed Oct 15, 2014
2 parents 9cb2b3a + b42a91d commit 7c1054e
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 33 deletions.
6 changes: 2 additions & 4 deletions components/layout/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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};
Expand Down Expand Up @@ -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
}
Expand Down
17 changes: 8 additions & 9 deletions components/script/dom/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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};

Expand Down Expand Up @@ -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>,
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down
68 changes: 68 additions & 0 deletions components/script/dom/bindings/cell.rs
Original file line number Diff line number Diff line change
@@ -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)
}
}
10 changes: 4 additions & 6 deletions components/script/dom/characterdata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand All @@ -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 {
Expand All @@ -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),
}
}

Expand All @@ -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()
}

}
Expand Down
25 changes: 11 additions & 14 deletions components/script/dom/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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};
Expand All @@ -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>,
}
Expand Down Expand Up @@ -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),
}
}

Expand Down Expand Up @@ -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
}
}
Expand All @@ -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() &&
Expand All @@ -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() {
Expand All @@ -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() &&
Expand All @@ -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")
Expand All @@ -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")
Expand Down
1 change: 1 addition & 0 deletions components/script/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 7c1054e

Please sign in to comment.