auto merge of #3979 : Ms2ger/servo/as_unsafe_cell, r=jdm

This commit is contained in:
bors-servo 2014-11-14 15:48:35 -07:00
commit 7d3b76c60d
9 changed files with 33 additions and 102 deletions

View file

@ -37,7 +37,6 @@ use util::{LayoutDataAccess, LayoutDataFlags, LayoutDataWrapper, OpaqueNodeMetho
use util::{PrivateLayoutData};
use gfx::display_list::OpaqueNode;
use script::dom::bindings::cell::{Ref, RefMut};
use script::dom::bindings::codegen::InheritTypes::{ElementCast, HTMLIFrameElementCast};
use script::dom::bindings::codegen::InheritTypes::{HTMLImageElementCast, HTMLInputElementCast};
use script::dom::bindings::codegen::InheritTypes::{TextCast};
@ -62,6 +61,8 @@ use style::{PropertyDeclarationBlock, SpecificNamespace, TElement, TElementAttri
use url::Url;
use string_cache::{Atom, Namespace};
use std::cell::{Ref, RefMut};
/// Allows some convenience methods on generic layout nodes.
pub trait TLayoutNode {
/// Creates a new layout node with the same lifetime as this layout node.

View file

@ -2,7 +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::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::AttrBinding;
use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
use dom::bindings::codegen::InheritTypes::NodeCast;
@ -16,9 +16,12 @@ use dom::virtualmethods::vtable_for;
use devtools_traits::AttrInfo;
use servo_util::str::{DOMString, split_html_space_chars};
use std::mem;
use string_cache::{Atom, Namespace};
use std::cell::Ref;
use std::mem;
pub enum AttrSettingType {
FirstSetAttr,
ReplacedAttr,

View file

@ -8,18 +8,14 @@ use js::jsapi::{JSTracer};
use servo_util::task_state;
use servo_util::task_state::{SCRIPT, IN_GC};
use std::cell::{Cell, UnsafeCell};
use std::kinds::marker;
use std::cell::{RefCell, Ref, RefMut};
/// A mutable field in the DOM.
///
/// This extends the API of `core::cell::RefCell` to allow unsafe access in
/// certain situations, with dynamic checking in debug builds.
pub struct DOMRefCell<T> {
value: UnsafeCell<T>,
borrow: Cell<BorrowFlag>,
nocopy: marker::NoCopy,
nosync: marker::NoSync,
value: RefCell<T>,
}
// Functionality specific to Servo's `DOMRefCell` type
@ -31,7 +27,7 @@ impl<T> DOMRefCell<T> {
/// For use in the layout task only.
pub unsafe fn borrow_for_layout<'a>(&'a self) -> &'a T {
debug_assert!(task_state::get().is_layout());
&*self.value.get()
&*self.value.as_unsafe_cell().get()
}
/// Borrow the contents for the purpose of GC tracing.
@ -40,36 +36,24 @@ impl<T> DOMRefCell<T> {
/// so you have to be careful in trace code!
pub unsafe fn borrow_for_gc_trace<'a>(&'a self) -> &'a T {
debug_assert!(task_state::get().contains(SCRIPT | IN_GC));
&*self.value.get()
&*self.value.as_unsafe_cell().get()
}
/// Is the cell mutably borrowed?
///
/// For safety checks in debug builds only.
pub fn is_mutably_borrowed(&self) -> bool {
self.borrow.get() == WRITING
self.value.try_borrow().is_some()
}
pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
debug_assert!(task_state::get().is_script());
match self.borrow.get() {
WRITING => None,
borrow => {
self.borrow.set(borrow + 1);
Some(Ref { _parent: self })
}
}
self.value.try_borrow()
}
pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> {
debug_assert!(task_state::get().is_script());
match self.borrow.get() {
UNUSED => {
self.borrow.set(WRITING);
Some(RefMut { _parent: self })
},
_ => None
}
self.value.try_borrow_mut()
}
}
@ -81,28 +65,15 @@ impl<T: JSTraceable> JSTraceable for DOMRefCell<T> {
// Functionality duplicated with `core::cell::RefCell`
// ===================================================
//
// This can shrink once rust-lang/rust#18131 is fixed.
// Values [1, MAX-1] represent the number of `Ref` active
// (will not outgrow its range since `uint` is the size of the address space)
type BorrowFlag = uint;
const UNUSED: BorrowFlag = 0;
const WRITING: BorrowFlag = -1;
impl<T> DOMRefCell<T> {
pub fn new(value: T) -> DOMRefCell<T> {
DOMRefCell {
value: UnsafeCell::new(value),
borrow: Cell::new(UNUSED),
nocopy: marker::NoCopy,
nosync: marker::NoSync,
value: RefCell::new(value),
}
}
pub fn unwrap(self) -> T {
debug_assert!(self.borrow.get() == UNUSED);
unsafe{self.value.unwrap()}
self.value.unwrap()
}
pub fn borrow<'a>(&'a self) -> Ref<'a, T> {
@ -119,50 +90,3 @@ impl<T> DOMRefCell<T> {
}
}
}
pub struct Ref<'b, T:'b> {
_parent: &'b DOMRefCell<T>
}
#[unsafe_destructor]
impl<'b, T> Drop for Ref<'b, T> {
fn drop(&mut self) {
let borrow = self._parent.borrow.get();
debug_assert!(borrow != WRITING && borrow != UNUSED);
self._parent.borrow.set(borrow - 1);
}
}
impl<'b, T> Deref<T> for Ref<'b, T> {
#[inline]
fn deref<'a>(&'a self) -> &'a T {
unsafe { &*self._parent.value.get() }
}
}
pub struct RefMut<'b, T:'b> {
_parent: &'b DOMRefCell<T>
}
#[unsafe_destructor]
impl<'b, T> Drop for RefMut<'b, T> {
fn drop(&mut self) {
let borrow = self._parent.borrow.get();
debug_assert!(borrow == WRITING);
self._parent.borrow.set(UNUSED);
}
}
impl<'b, T> Deref<T> for RefMut<'b, T> {
#[inline]
fn deref<'a>(&'a self) -> &'a T {
unsafe { &*self._parent.value.get() }
}
}
impl<'b, T> DerefMut<T> for RefMut<'b, T> {
#[inline]
fn deref_mut<'a>(&'a mut self) -> &'a mut T {
unsafe { &mut *self._parent.value.get() }
}
}

View file

@ -469,13 +469,11 @@ impl Reflector {
self.object.set(object);
}
/// Return a pointer to the memory location at which the JS reflector object is stored.
/// Used by Temporary values to root the reflector, as required by the JSAPI rooting
/// APIs.
pub fn rootable(&self) -> *mut *mut JSObject {
&self.object as *const Cell<*mut JSObject>
as *mut Cell<*mut JSObject>
as *mut *mut JSObject
/// Return a pointer to the memory location at which the JS reflector
/// object is stored. Used by Temporary values to root the reflector, as
/// required by the JSAPI rooting APIs.
pub unsafe fn rootable(&self) -> *mut *mut JSObject {
self.object.as_unsafe_cell().get()
}
/// Create an uninitialized `Reflector`.

View file

@ -4,7 +4,7 @@
//! DOM bindings for `CharacterData`.
use dom::bindings::cell::{DOMRefCell, Ref};
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods;
use dom::bindings::codegen::InheritTypes::{CharacterDataDerived, NodeCast};
use dom::bindings::error::{Fallible, ErrorResult, IndexSize};
@ -13,8 +13,11 @@ use dom::bindings::utils::{Reflectable, Reflector};
use dom::document::Document;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::node::{CommentNodeTypeId, Node, NodeTypeId, TextNodeTypeId, ProcessingInstructionNodeTypeId, NodeHelpers};
use servo_util::str::DOMString;
use std::cell::Ref;
#[dom_struct]
pub struct CharacterData {
node: Node,

View file

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::attr::AttrHelpers;
use dom::bindings::cell::{DOMRefCell, Ref};
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::DocumentBinding;
use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, DocumentReadyState};
use dom::bindings::codegen::Bindings::DocumentBinding::DocumentReadyStateValues;
@ -65,7 +65,7 @@ use url::Url;
use std::collections::HashMap;
use std::collections::hash_map::{Vacant, Occupied};
use std::ascii::AsciiExt;
use std::cell::Cell;
use std::cell::{Cell, Ref};
use std::default::Default;
use time;

View file

@ -7,7 +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::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
use dom::bindings::codegen::Bindings::ElementBinding;
use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods;
@ -41,6 +41,7 @@ use servo_util::namespace;
use servo_util::str::{DOMString, LengthOrPercentageOrAuto};
use std::ascii::AsciiExt;
use std::cell::{Ref, RefMut};
use std::default::Default;
use std::mem;
use string_cache::{Atom, Namespace, QualName};

View file

@ -2,7 +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, RefMut};
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::EventHandlerBinding::{OnErrorEventHandlerNonNull, EventHandlerNonNull};
use dom::bindings::codegen::Bindings::WindowBinding;
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
@ -40,6 +40,7 @@ use url::{Url, UrlParser};
use libc;
use serialize::base64::{FromBase64, ToBase64, STANDARD};
use std::cell::{Ref, RefMut};
use std::default::Default;
use std::rc::Rc;
use time;

View file

@ -2,7 +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, RefMut};
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
use dom::bindings::codegen::InheritTypes::NodeCast;
use dom::bindings::js::{JS, JSRef, Temporary, OptionalRootable};
@ -30,7 +30,7 @@ use servo_util::geometry::{Au, MAX_RECT};
use servo_util::geometry;
use servo_util::str::DOMString;
use servo_util::smallvec::{SmallVec1, SmallVec};
use std::cell::Cell;
use std::cell::{Cell, Ref, RefMut};
use std::comm::{channel, Receiver, Empty, Disconnected};
use std::mem::replace;
use std::num::abs;