Upgrade to latest Rust.

This commit is contained in:
Jack Moffitt 2013-12-20 22:04:46 -07:00
parent 728fb9a7de
commit a7ef1cd35e
127 changed files with 1892 additions and 2501 deletions

View file

@ -7,7 +7,6 @@
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::utils::{DOMString, null_str_as_empty};
use dom::bindings::utils::{ErrorResult, Fallible, NotFound, HierarchyRequest};
use dom::bindings::utils;
use dom::characterdata::CharacterData;
use dom::document::{AbstractDocument, DocumentTypeId};
use dom::documenttype::DocumentType;
@ -20,12 +19,15 @@ use dom::nodelist::{NodeList};
use dom::text::Text;
use js::jsapi::{JSObject, JSContext};
use servo_util::slot::{MutSlotRef, Slot, SlotRef};
use std::cast::transmute;
use layout_interface::{LayoutChan, ReapLayoutDataMsg};
use std::cast;
use std::unstable::raw::Box;
use std::util;
use std::cast::transmute;
use std::cell::{RefCell, Ref, RefMut};
use std::iter::Filter;
use std::util;
use std::unstable::raw::Box;
//
// The basic Node structure
@ -37,7 +39,7 @@ use std::iter::Filter;
/// FIXME: This should be replaced with a trait once they can inherit from structs.
#[deriving(Eq)]
pub struct AbstractNode {
priv obj: *mut Box<Node>,
priv obj: *mut (),
}
/// An HTML node.
@ -109,30 +111,43 @@ impl Drop for Node {
}
/// Encapsulates the abstract layout data.
pub struct LayoutData {
priv chan: Option<LayoutChan>,
priv data: *(),
}
pub struct LayoutDataRef {
priv data: Slot<Option<*()>>,
data_cell: RefCell<Option<LayoutData>>,
}
impl LayoutDataRef {
#[inline]
pub fn init() -> LayoutDataRef {
pub fn new() -> LayoutDataRef {
LayoutDataRef {
data: Slot::init(None),
data_cell: RefCell::new(None),
}
}
/// Creates a new piece of layout data from a value.
#[inline]
pub unsafe fn from_data<T>(data: ~T) -> LayoutDataRef {
LayoutDataRef {
data: Slot::init(Some(cast::transmute(data))),
data_cell: RefCell::new(Some(cast::transmute(data))),
}
}
/// Returns true if this layout data is present or false otherwise.
/// Returns true if there is layout data present.
#[inline]
pub fn is_present(&self) -> bool {
self.data.get().is_some()
let data_ref = self.data_cell.borrow();
data_ref.get().is_some()
}
/// Take the chan out of the layout data if it is present.
pub fn take_chan(&self) -> Option<LayoutChan> {
let mut data_ref = self.data_cell.borrow_mut();
let layout_data = data_ref.get();
match *layout_data {
None => None,
Some(..) => Some(layout_data.get_mut_ref().chan.take_unwrap()),
}
}
/// Borrows the layout data immutably, *asserting that there are no mutators*. Bad things will
@ -141,17 +156,15 @@ impl LayoutDataRef {
///
/// FIXME(pcwalton): Enforce this invariant via the type system. Will require traversal
/// functions to be trusted, but c'est la vie.
#[inline]
pub unsafe fn borrow_unchecked<'a>(&'a self) -> &'a () {
cast::transmute(self.data.borrow_unchecked())
}
// #[inline]
// pub unsafe fn borrow_unchecked<'a>(&'a self) -> &'a () {
// self.data.borrow_unchecked()
// }
/// Borrows the layout data immutably. This function is *not* thread-safe.
#[inline]
pub fn borrow<'a>(&'a self) -> SlotRef<'a,()> {
unsafe {
cast::transmute(self.data.borrow())
}
pub fn borrow<'a>(&'a self) -> Ref<'a,Option<LayoutData>> {
self.data_cell.borrow()
}
/// Borrows the layout data mutably. This function is *not* thread-safe.
@ -160,10 +173,8 @@ impl LayoutDataRef {
/// prevent CSS selector matching from mutably accessing nodes it's not supposed to and racing
/// on it. This has already resulted in one bug!
#[inline]
pub fn mutate<'a>(&'a self) -> MutSlotRef<'a,()> {
unsafe {
cast::transmute(self.data.mutate())
}
pub fn borrow_mut<'a>(&'a self) -> RefMut<'a,Option<LayoutData>> {
self.data_cell.borrow_mut()
}
}
@ -193,13 +204,15 @@ impl Clone for AbstractNode {
impl AbstractNode {
pub fn node<'a>(&'a self) -> &'a Node {
unsafe {
&(*self.obj).data
let box_: *mut Box<Node> = cast::transmute(self.obj);
&(*box_).data
}
}
pub fn mut_node<'a>(&'a self) -> &'a mut Node {
unsafe {
&mut (*self.obj).data
let box_: *mut Box<Node> = cast::transmute(self.obj);
&mut (*box_).data
}
}
@ -217,20 +230,20 @@ impl AbstractNode {
pub fn is_element(&self) -> bool {
match self.type_id() {
ElementNodeTypeId(*) => true,
ElementNodeTypeId(..) => true,
_ => false
}
}
pub fn is_document(&self) -> bool {
match self.type_id() {
DocumentNodeTypeId(*) => true,
DocumentNodeTypeId(..) => true,
_ => false
}
}
}
impl<'self> AbstractNode {
impl<'a> AbstractNode {
// Unsafe accessors
pub unsafe fn as_cacheable_wrapper(&self) -> @mut Reflectable {
@ -252,7 +265,7 @@ impl<'self> AbstractNode {
/// FIXME(pcwalton): Mark unsafe?
pub fn from_box<T>(ptr: *mut Box<T>) -> AbstractNode {
AbstractNode {
obj: ptr as *mut Box<Node>
obj: ptr as *mut ()
}
}
@ -291,27 +304,27 @@ impl<'self> AbstractNode {
// Downcasting borrows
//
pub fn transmute<T, R>(self, f: &fn(&T) -> R) -> R {
pub fn transmute<'a, T, R>(self, f: |&'a T| -> R) -> R {
unsafe {
let node_box: *mut Box<Node> = transmute(self.obj);
let node = &mut (*node_box).data;
let old = node.abstract;
node.abstract = Some(self);
let box: *Box<T> = transmute(self.obj);
let rv = f(&(*box).data);
let box_: *Box<T> = transmute(self.obj);
let rv = f(&(*box_).data);
node.abstract = old;
rv
}
}
pub fn transmute_mut<T, R>(self, f: &fn(&mut T) -> R) -> R {
pub fn transmute_mut<T, R>(self, f: |&mut T| -> R) -> R {
unsafe {
let node_box: *mut Box<Node> = transmute(self.obj);
let node = &mut (*node_box).data;
let old = node.abstract;
node.abstract = Some(self);
let box: *Box<T> = transmute(self.obj);
let rv = f(cast::transmute(&(*box).data));
let box_: *Box<T> = transmute(self.obj);
let rv = f(cast::transmute(&(*box_).data));
node.abstract = old;
rv
}
@ -323,14 +336,14 @@ impl<'self> AbstractNode {
self.is_text() || self.is_comment()
}
pub fn with_imm_characterdata<R>(self, f: &fn(&CharacterData) -> R) -> R {
pub fn with_imm_characterdata<R>(self, f: |&CharacterData| -> R) -> R {
if !self.is_characterdata() {
fail!(~"node is not characterdata");
}
self.transmute(f)
}
pub fn with_mut_characterdata<R>(self, f: &fn(&mut CharacterData) -> R) -> R {
pub fn with_mut_characterdata<R>(self, f: |&mut CharacterData| -> R) -> R {
if !self.is_characterdata() {
fail!(~"node is not characterdata");
}
@ -341,14 +354,14 @@ impl<'self> AbstractNode {
self.type_id() == DoctypeNodeTypeId
}
pub fn with_imm_doctype<R>(self, f: &fn(&DocumentType) -> R) -> R {
pub fn with_imm_doctype<R>(self, f: |&DocumentType| -> R) -> R {
if !self.is_doctype() {
fail!(~"node is not doctype");
}
self.transmute(f)
}
pub fn with_mut_doctype<R>(self, f: &fn(&mut DocumentType) -> R) -> R {
pub fn with_mut_doctype<R>(self, f: |&mut DocumentType| -> R) -> R {
if !self.is_doctype() {
fail!(~"node is not doctype");
}
@ -375,14 +388,14 @@ impl<'self> AbstractNode {
}
}
pub fn with_imm_text<R>(self, f: &fn(&Text) -> R) -> R {
pub fn with_imm_text<R>(self, f: |&Text| -> R) -> R {
if !self.is_text() {
fail!(~"node is not text");
}
self.transmute(f)
}
pub fn with_mut_text<R>(self, f: &fn(&mut Text) -> R) -> R {
pub fn with_mut_text<R>(self, f: |&mut Text| -> R) -> R {
if !self.is_text() {
fail!(~"node is not text");
}
@ -390,7 +403,7 @@ impl<'self> AbstractNode {
}
// FIXME: This should be doing dynamic borrow checking for safety.
pub fn with_imm_element<R>(self, f: &fn(&Element) -> R) -> R {
pub fn with_imm_element<R>(self, f: |&Element| -> R) -> R {
if !self.is_element() {
fail!(~"node is not an element");
}
@ -398,7 +411,7 @@ impl<'self> AbstractNode {
}
// FIXME: This should be doing dynamic borrow checking for safety.
pub fn as_mut_element<R>(self, f: &fn(&mut Element) -> R) -> R {
pub fn as_mut_element<R>(self, f: |&mut Element| -> R) -> R {
if !self.is_element() {
fail!(~"node is not an element");
}
@ -413,7 +426,7 @@ impl<'self> AbstractNode {
}
}
pub fn with_mut_image_element<R>(self, f: &fn(&mut HTMLImageElement) -> R) -> R {
pub fn with_mut_image_element<R>(self, f: |&mut HTMLImageElement| -> R) -> R {
if !self.is_image_element() {
fail!(~"node is not an image element");
}
@ -424,7 +437,7 @@ impl<'self> AbstractNode {
self.type_id() == ElementNodeTypeId(HTMLIframeElementTypeId)
}
pub fn with_mut_iframe_element<R>(self, f: &fn(&mut HTMLIFrameElement) -> R) -> R {
pub fn with_mut_iframe_element<R>(self, f: |&mut HTMLIFrameElement| -> R) -> R {
if !self.is_iframe_element() {
fail!(~"node is not an iframe element");
}
@ -440,12 +453,12 @@ impl<'self> AbstractNode {
}
pub unsafe fn raw_object(self) -> *mut Box<Node> {
self.obj
cast::transmute(self.obj)
}
pub fn from_raw(raw: *mut Box<Node>) -> AbstractNode {
AbstractNode {
obj: raw
obj: raw as *mut ()
}
}
@ -479,10 +492,6 @@ impl<'self> AbstractNode {
// Convenience accessors
//
fn is_leaf(&self) -> bool {
self.first_child().is_none()
}
pub fn children(&self) -> AbstractNodeChildrenIterator {
self.node().children()
}
@ -610,35 +619,6 @@ impl AbstractNode {
child_node.set_next_sibling(None);
child_node.set_parent_node(None);
}
//
// Low-level pointer stitching wrappers
//
fn set_parent_node(&self, new_parent_node: Option<AbstractNode>) {
let node = self.mut_node();
node.set_parent_node(new_parent_node)
}
fn set_first_child(&self, new_first_child: Option<AbstractNode>) {
let node = self.mut_node();
node.set_first_child(new_first_child)
}
fn set_last_child(&self, new_last_child: Option<AbstractNode>) {
let node = self.mut_node();
node.set_last_child(new_last_child)
}
fn set_prev_sibling(&self, new_prev_sibling: Option<AbstractNode>) {
let node = self.mut_node();
node.set_prev_sibling(new_prev_sibling)
}
fn set_next_sibling(&self, new_next_sibling: Option<AbstractNode>) {
let node = self.mut_node();
node.set_next_sibling(new_next_sibling)
}
}
//
@ -652,9 +632,9 @@ pub struct AbstractNodeChildrenIterator {
impl Iterator<AbstractNode> for AbstractNodeChildrenIterator {
fn next(&mut self) -> Option<AbstractNode> {
let node = self.current_node;
self.current_node = do self.current_node.and_then |node| {
self.current_node = self.current_node.and_then(|node| {
node.next_sibling()
};
});
node
}
}
@ -766,9 +746,9 @@ impl Node {
assert!(node.reflector().get_jsobject().is_null());
let node = reflect_dom_object(node, document.document().window, wrap_fn);
assert!(node.reflector().get_jsobject().is_not_null());
// This surrenders memory management of the node!
// JS owns the node now, so transmute_copy to not increase the refcount
AbstractNode {
obj: unsafe { transmute(node) },
obj: unsafe { cast::transmute_copy(&node) },
}
}
@ -798,16 +778,19 @@ impl Node {
flags: NodeFlags::new(type_id),
layout_data: LayoutDataRef::init(),
layout_data: LayoutDataRef::new(),
}
}
/// Sends layout data, if any, back to the script task to be destroyed.
pub unsafe fn reap_layout_data(&mut self) {
if self.layout_data.is_present() {
let layout_data = util::replace(&mut self.layout_data, LayoutDataRef::init());
let js_window = utils::global_object_for_dom_object(self);
(*js_window).data.page.reap_dead_layout_data(layout_data)
let layout_data = util::replace(&mut self.layout_data, LayoutDataRef::new());
let layout_chan = layout_data.take_chan();
match layout_chan {
None => {}
Some(chan) => chan.send(ReapLayoutDataMsg(layout_data)),
}
}
}
@ -825,17 +808,17 @@ impl Node {
pub fn NodeName(&self, abstract_self: AbstractNode) -> DOMString {
match self.type_id {
ElementNodeTypeId(*) => {
do abstract_self.with_imm_element |element| {
ElementNodeTypeId(..) => {
abstract_self.with_imm_element(|element| {
element.TagName()
}
})
}
CommentNodeTypeId => ~"#comment",
TextNodeTypeId => ~"#text",
DoctypeNodeTypeId => {
do abstract_self.with_imm_doctype |doctype| {
abstract_self.with_imm_doctype(|doctype| {
doctype.name.clone()
}
})
},
DocumentFragmentNodeTypeId => ~"#document-fragment",
DocumentNodeTypeId(_) => ~"#document"
@ -848,7 +831,7 @@ impl Node {
pub fn GetOwnerDocument(&self) -> Option<AbstractDocument> {
match self.type_id {
ElementNodeTypeId(*) |
ElementNodeTypeId(..) |
CommentNodeTypeId |
TextNodeTypeId |
DoctypeNodeTypeId |
@ -889,9 +872,9 @@ impl Node {
match self.type_id {
// ProcessingInstruction
CommentNodeTypeId | TextNodeTypeId => {
do abstract_self.with_imm_characterdata() |characterdata| {
abstract_self.with_imm_characterdata(|characterdata| {
Some(characterdata.Data())
}
})
}
_ => {
None
@ -906,21 +889,21 @@ impl Node {
pub fn GetTextContent(&self, abstract_self: AbstractNode) -> Option<DOMString> {
match self.type_id {
DocumentFragmentNodeTypeId | ElementNodeTypeId(*) => {
DocumentFragmentNodeTypeId | ElementNodeTypeId(..) => {
let mut content = ~"";
for node in abstract_self.traverse_preorder() {
if node.is_text() {
do node.with_imm_text() |text| {
node.with_imm_text(|text| {
content = content + text.element.Data();
}
})
}
}
Some(content)
}
CommentNodeTypeId | TextNodeTypeId => {
do abstract_self.with_imm_characterdata() |characterdata| {
abstract_self.with_imm_characterdata(|characterdata| {
Some(characterdata.Data())
}
})
}
DoctypeNodeTypeId | DocumentNodeTypeId(_) => {
None
@ -968,9 +951,9 @@ impl Node {
// Step 1.
match parent.type_id() {
DocumentNodeTypeId(*) |
DocumentNodeTypeId(..) |
DocumentFragmentNodeTypeId |
ElementNodeTypeId(*) => (),
ElementNodeTypeId(..) => (),
_ => {
return Err(HierarchyRequest);
},
@ -999,7 +982,7 @@ impl Node {
TextNodeTypeId |
// ProcessingInstructionNodeTypeId |
CommentNodeTypeId => (),
DocumentNodeTypeId(*) => return Err(HierarchyRequest),
DocumentNodeTypeId(..) => return Err(HierarchyRequest),
}
// Step 5.
@ -1241,7 +1224,7 @@ impl Node {
-> ErrorResult {
let value = null_str_as_empty(&value);
match self.type_id {
DocumentFragmentNodeTypeId | ElementNodeTypeId(*) => {
DocumentFragmentNodeTypeId | ElementNodeTypeId(..) => {
// Step 1-2.
let node = if value.len() == 0 {
None
@ -1255,13 +1238,13 @@ impl Node {
CommentNodeTypeId | TextNodeTypeId => {
self.wait_until_safe_to_modify_dom();
do abstract_self.with_mut_characterdata() |characterdata| {
abstract_self.with_mut_characterdata(|characterdata| {
characterdata.data = value.clone();
// Notify the document that the content of this node is different
let document = self.owner_doc();
document.document().content_changed();
}
})
}
DoctypeNodeTypeId | DocumentNodeTypeId(_) => {}
}