servo: Merge #2649 - Replace uses of JS<T>.unrooted() with JS::from_rooted #2580 (from ebalint:2580_JS_T_unrooted_replace); r=jdm
authorEdit Balint <edbalint@inf.u-szeged.hu>
Fri, 13 Jun 2014 14:33:03 -0400
changeset 334524 4172c458bfb06584f46d18c1e2c3db039cb4c29b
parent 334523 5d26c94d9768879e2262db9efc23bea5d98abe57
child 334525 b5687abaf36e3a800d26ea6bb76efe422d23b70c
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdm
servo: Merge #2649 - Replace uses of JS<T>.unrooted() with JS::from_rooted #2580 (from ebalint:2580_JS_T_unrooted_replace); r=jdm removed .clone() calls modified from_rooted method parameter: T to &T Source-Repo: https://github.com/servo/servo Source-Revision: 7ed504189198ac2f59c396d5872046ac7c9578b3
servo/src/components/script/dom/attr.rs
servo/src/components/script/dom/attrlist.rs
servo/src/components/script/dom/bindings/js.rs
servo/src/components/script/dom/blob.rs
servo/src/components/script/dom/browsercontext.rs
servo/src/components/script/dom/clientrect.rs
servo/src/components/script/dom/clientrectlist.rs
servo/src/components/script/dom/document.rs
servo/src/components/script/dom/domimplementation.rs
servo/src/components/script/dom/domparser.rs
servo/src/components/script/dom/domtokenlist.rs
servo/src/components/script/dom/eventdispatcher.rs
servo/src/components/script/dom/formdata.rs
servo/src/components/script/dom/htmlcollection.rs
servo/src/components/script/dom/node.rs
servo/src/components/script/dom/nodelist.rs
servo/src/components/script/dom/performance.rs
servo/src/components/script/dom/validitystate.rs
servo/src/components/script/dom/xmlhttprequest.rs
servo/src/components/script/script_task.rs
--- a/servo/src/components/script/dom/attr.rs
+++ b/servo/src/components/script/dom/attr.rs
@@ -79,17 +79,17 @@ impl Attr {
                      prefix: Option<DOMString>, owner: &JSRef<Element>) -> Attr {
         Attr {
             reflector_: Reflector::new(),
             local_name: local_name,
             value: value,
             name: name, //TODO: Intern attribute names
             namespace: namespace,
             prefix: prefix,
-            owner: Cell::new(owner.unrooted()),
+            owner: Cell::new(JS::from_rooted(owner)),
         }
     }
 
     pub fn new(window: &JSRef<Window>, local_name: DOMString, value: AttrValue,
                name: DOMString, namespace: Namespace,
                prefix: Option<DOMString>, owner: &JSRef<Element>) -> Temporary<Attr> {
         let attr = Attr::new_inherited(local_name, value, name, namespace, prefix, owner);
         reflect_dom_object(box attr, window, AttrBinding::Wrap)
--- a/servo/src/components/script/dom/attrlist.rs
+++ b/servo/src/components/script/dom/attrlist.rs
@@ -15,18 +15,18 @@ pub struct AttrList {
     pub window: JS<Window>,
     pub owner: JS<Element>,
 }
 
 impl AttrList {
     pub fn new_inherited(window: &JSRef<Window>, elem: &JSRef<Element>) -> AttrList {
         AttrList {
             reflector_: Reflector::new(),
-            window: window.unrooted(),
-            owner: elem.unrooted(),
+            window: JS::from_rooted(window),
+            owner: JS::from_rooted(elem),
         }
     }
 
     pub fn new(window: &JSRef<Window>, elem: &JSRef<Element>) -> Temporary<AttrList> {
         reflect_dom_object(box AttrList::new_inherited(window, elem),
                            window, AttrListBinding::Wrap)
     }
 }
--- a/servo/src/components/script/dom/bindings/js.rs
+++ b/servo/src/components/script/dom/bindings/js.rs
@@ -72,17 +72,17 @@ impl<T: Reflectable> Temporary<T> {
         Temporary {
             inner: inner,
             js_ptr: inner.reflector().get_jsobject(),
         }
     }
 
     /// Create a new Temporary value from a rooted value.
     pub fn from_rooted<'a>(root: &JSRef<'a, T>) -> Temporary<T> {
-        Temporary::new(root.unrooted())
+        Temporary::new(JS::from_rooted(root))
     }
 
     /// Create a stack-bounded root for this value.
     pub fn root<'a, 'b>(self) -> Root<'a, 'b, T> {
         let collection = StackRoots.get().unwrap();
         unsafe {
             (**collection).new_root(&self.inner)
         }
@@ -151,17 +151,17 @@ impl<T: Reflectable> JS<T> {
         let collection = StackRoots.get().unwrap();
         unsafe {
             (**collection).new_root(self)
         }
     }
 }
 
 impl<T: Assignable<U>, U: Reflectable> JS<U> {
-    pub fn from_rooted(root: T) -> JS<U> {
+    pub fn from_rooted(root: &T) -> JS<U> {
         unsafe {
             root.get_js()
         }
     }
 }
 
 //XXXjdm This is disappointing. This only gets called from trace hooks, in theory,
 //       so it's safe to assume that self is rooted and thereby safe to access.
@@ -274,17 +274,17 @@ impl<T: Reflectable> OptionalRootable<T>
 
 /// Return an unrooted type for storing in optional DOM fields
 pub trait OptionalUnrootable<T> {
     fn unrooted(&self) -> Option<JS<T>>;
 }
 
 impl<'a, T: Reflectable> OptionalUnrootable<T> for Option<JSRef<'a, T>> {
     fn unrooted(&self) -> Option<JS<T>> {
-        self.as_ref().map(|inner| inner.unrooted())
+        self.as_ref().map(|inner| JS::from_rooted(inner))
     }
 }
 
 /// Root a rootable Option type (used for Option<JS<T>>)
 pub trait OptionalRootedRootable<T> {
     fn root<'a, 'b>(&self) -> Option<Root<'a, 'b, T>>;
 }
 
--- a/servo/src/components/script/dom/blob.rs
+++ b/servo/src/components/script/dom/blob.rs
@@ -13,17 +13,17 @@ pub struct Blob {
     pub reflector_: Reflector,
     pub window: JS<Window>
 }
 
 impl Blob {
     pub fn new_inherited(window: &JSRef<Window>) -> Blob {
         Blob {
             reflector_: Reflector::new(),
-            window: window.unrooted()
+            window: JS::from_rooted(window)
         }
     }
 
     pub fn new(window: &JSRef<Window>) -> Temporary<Blob> {
         reflect_dom_object(box Blob::new_inherited(window),
                            window,
                            BlobBinding::Wrap)
     }
--- a/servo/src/components/script/dom/browsercontext.rs
+++ b/servo/src/components/script/dom/browsercontext.rs
@@ -70,17 +70,17 @@ impl BrowserContext {
 pub struct SessionHistoryEntry {
     document: JS<Document>,
     children: Vec<BrowserContext>
 }
 
 impl SessionHistoryEntry {
     fn new(document: &JSRef<Document>) -> SessionHistoryEntry {
         SessionHistoryEntry {
-            document: document.unrooted(),
+            document: JS::from_rooted(document),
             children: vec!()
         }
     }
 }
 
 static proxy_handler: ProxyTraps = ProxyTraps {
     getPropertyDescriptor: None,
     getOwnPropertyDescriptor: None,
--- a/servo/src/components/script/dom/clientrect.rs
+++ b/servo/src/components/script/dom/clientrect.rs
@@ -23,17 +23,17 @@ impl ClientRect {
                          top: Au, bottom: Au,
                          left: Au, right: Au) -> ClientRect {
         ClientRect {
             top: top.to_nearest_px() as f32,
             bottom: bottom.to_nearest_px() as f32,
             left: left.to_nearest_px() as f32,
             right: right.to_nearest_px() as f32,
             reflector_: Reflector::new(),
-            window: window.unrooted(),
+            window: JS::from_rooted(window),
         }
     }
 
     pub fn new(window: &JSRef<Window>,
                top: Au, bottom: Au,
                left: Au, right: Au) -> Temporary<ClientRect> {
         let rect = ClientRect::new_inherited(window, top, bottom, left, right);
         reflect_dom_object(box rect, window, ClientRectBinding::Wrap)
--- a/servo/src/components/script/dom/clientrectlist.rs
+++ b/servo/src/components/script/dom/clientrectlist.rs
@@ -13,21 +13,21 @@ pub struct ClientRectList {
     pub reflector_: Reflector,
     pub rects: Vec<JS<ClientRect>>,
     pub window: JS<Window>,
 }
 
 impl ClientRectList {
     pub fn new_inherited(window: &JSRef<Window>,
                          rects: Vec<JSRef<ClientRect>>) -> ClientRectList {
-        let rects = rects.iter().map(|rect| rect.unrooted()).collect();
+        let rects = rects.iter().map(|rect| JS::from_rooted(rect)).collect();
         ClientRectList {
             reflector_: Reflector::new(),
             rects: rects,
-            window: window.unrooted(),
+            window: JS::from_rooted(window),
         }
     }
 
     pub fn new(window: &JSRef<Window>,
                rects: Vec<JSRef<ClientRect>>) -> Temporary<ClientRectList> {
         reflect_dom_object(box ClientRectList::new_inherited(window, rects),
                            window, ClientRectListBinding::Wrap)
     }
--- a/servo/src/components/script/dom/document.rs
+++ b/servo/src/components/script/dom/document.rs
@@ -210,17 +210,17 @@ impl Document {
                          url: Option<Url>,
                          is_html_document: IsHTMLDocument,
                          content_type: Option<DOMString>) -> Document {
         let url = url.unwrap_or_else(|| from_str("about:blank").unwrap());
 
         Document {
             node: Node::new_without_doc(DocumentNodeTypeId),
             reflector_: Reflector::new(),
-            window: window.unrooted(),
+            window: JS::from_rooted(window),
             idmap: Traceable::new(RefCell::new(HashMap::new())),
             implementation: Cell::new(None),
             content_type: match content_type {
                 Some(string) => string.clone(),
                 None => match is_html_document {
                     // http://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument
                     HTMLDocument => "text/html".to_string(),
                     // http://dom.spec.whatwg.org/#concept-document-content-type
--- a/servo/src/components/script/dom/domimplementation.rs
+++ b/servo/src/components/script/dom/domimplementation.rs
@@ -23,17 +23,17 @@ use servo_util::str::DOMString;
 pub struct DOMImplementation {
     pub owner: JS<Window>,
     pub reflector_: Reflector,
 }
 
 impl DOMImplementation {
     pub fn new_inherited(owner: &JSRef<Window>) -> DOMImplementation {
         DOMImplementation {
-            owner: owner.unrooted(),
+            owner: JS::from_rooted(owner),
             reflector_: Reflector::new(),
         }
     }
 
     pub fn new(owner: &JSRef<Window>) -> Temporary<DOMImplementation> {
         reflect_dom_object(box DOMImplementation::new_inherited(owner), owner,
                            DOMImplementationBinding::Wrap)
     }
--- a/servo/src/components/script/dom/domparser.rs
+++ b/servo/src/components/script/dom/domparser.rs
@@ -15,17 +15,17 @@ use servo_util::str::DOMString;
 pub struct DOMParser {
     pub owner: JS<Window>, //XXXjdm Document instead?
     pub reflector_: Reflector
 }
 
 impl DOMParser {
     pub fn new_inherited(owner: &JSRef<Window>) -> DOMParser {
         DOMParser {
-            owner: owner.unrooted(),
+            owner: JS::from_rooted(owner),
             reflector_: Reflector::new()
         }
     }
 
     pub fn new(owner: &JSRef<Window>) -> Temporary<DOMParser> {
         reflect_dom_object(box DOMParser::new_inherited(owner), owner,
                            DOMParserBinding::Wrap)
     }
--- a/servo/src/components/script/dom/domtokenlist.rs
+++ b/servo/src/components/script/dom/domtokenlist.rs
@@ -19,17 +19,17 @@ pub struct DOMTokenList {
     local_name: &'static str,
 }
 
 impl DOMTokenList {
     pub fn new_inherited(element: &JSRef<Element>,
                          local_name: &'static str) -> DOMTokenList {
         DOMTokenList {
             reflector_: Reflector::new(),
-            element: JS::from_rooted(element.clone()),
+            element: JS::from_rooted(element),
             local_name: local_name,
         }
     }
 
     pub fn new(element: &JSRef<Element>,
                local_name: &'static str) -> Temporary<DOMTokenList> {
         let window = window_from_node(element).root();
         reflect_dom_object(box DOMTokenList::new_inherited(element, local_name),
--- a/servo/src/components/script/dom/eventdispatcher.rs
+++ b/servo/src/components/script/dom/eventdispatcher.rs
@@ -1,15 +1,15 @@
 /* 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::callback::ReportExceptions;
 use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast, NodeDerived};
-use dom::bindings::js::{JSRef, OptionalSettable, OptionalRootable, Root};
+use dom::bindings::js::{JS, JSRef, OptionalSettable, OptionalRootable, Root};
 use dom::eventtarget::{Capturing, Bubbling, EventTarget};
 use dom::event::{Event, PhaseAtTarget, PhaseNone, PhaseBubbling, PhaseCapturing, EventMethods};
 use dom::node::{Node, NodeHelpers};
 use dom::virtualmethods::vtable_for;
 
 // See http://dom.spec.whatwg.org/#concept-event-dispatch for the full dispatch algorithm
 pub fn dispatch_event<'a, 'b>(target: &JSRef<'a, EventTarget>,
                               pseudo_target: Option<JSRef<'b, EventTarget>>,
@@ -24,17 +24,17 @@ pub fn dispatch_event<'a, 'b>(target: &J
 
     let type_ = event.Type();
 
     //TODO: no chain if not participating in a tree
     let mut chain: Vec<Root<EventTarget>> = if target.deref().is_node() {
         let target_node: &JSRef<Node> = NodeCast::to_ref(target).unwrap();
         target_node.ancestors().map(|ancestor| {
             let ancestor_target: &JSRef<EventTarget> = EventTargetCast::from_ref(&ancestor);
-            ancestor_target.unrooted().root()
+            JS::from_rooted(ancestor_target).root()
         }).collect()
     } else {
         vec!()
     };
 
     event.deref().phase.deref().set(PhaseCapturing);
 
     //FIXME: The "callback this value" should be currentTarget
--- a/servo/src/components/script/dom/formdata.rs
+++ b/servo/src/components/script/dom/formdata.rs
@@ -28,17 +28,17 @@ pub struct FormData {
     pub form: Option<JS<HTMLFormElement>>
 }
 
 impl FormData {
     pub fn new_inherited(form: Option<JSRef<HTMLFormElement>>, window: &JSRef<Window>) -> FormData {
         FormData {
             data: Traceable::new(RefCell::new(HashMap::new())),
             reflector_: Reflector::new(),
-            window: window.unrooted(),
+            window: JS::from_rooted(window),
             form: form.unrooted(),
         }
     }
 
     pub fn new(form: Option<JSRef<HTMLFormElement>>, window: &JSRef<Window>) -> Temporary<FormData> {
         reflect_dom_object(box FormData::new_inherited(form, window), window, FormDataBinding::Wrap)
     }
 
@@ -50,17 +50,17 @@ impl FormData {
 pub trait FormDataMethods {
     fn Append(&self, name: DOMString, value: &JSRef<Blob>, filename: Option<DOMString>);
     fn Append_(&self, name: DOMString, value: DOMString);
 }
 
 impl<'a> FormDataMethods for JSRef<'a, FormData> {
     fn Append(&self, name: DOMString, value: &JSRef<Blob>, filename: Option<DOMString>) {
         let blob = BlobData {
-            blob: value.unrooted(),
+            blob: JS::from_rooted(value),
             name: filename.unwrap_or("default".to_string())
         };
         self.data.deref().borrow_mut().insert(name.clone(), blob);
     }
 
     fn Append_(&self, name: DOMString, value: DOMString) {
         self.data.deref().borrow_mut().insert(name, StringData(value));
     }
--- a/servo/src/components/script/dom/htmlcollection.rs
+++ b/servo/src/components/script/dom/htmlcollection.rs
@@ -37,30 +37,30 @@ pub struct HTMLCollection {
     pub window: JS<Window>,
 }
 
 impl HTMLCollection {
     pub fn new_inherited(window: &JSRef<Window>, collection: CollectionTypeId) -> HTMLCollection {
         HTMLCollection {
             collection: collection,
             reflector_: Reflector::new(),
-            window: window.unrooted(),
+            window: JS::from_rooted(window),
         }
     }
 
     pub fn new(window: &JSRef<Window>, collection: CollectionTypeId) -> Temporary<HTMLCollection> {
         reflect_dom_object(box HTMLCollection::new_inherited(window, collection),
                            window, HTMLCollectionBinding::Wrap)
     }
 }
 
 impl HTMLCollection {
     pub fn create(window: &JSRef<Window>, root: &JSRef<Node>,
                   filter: Box<CollectionFilter>) -> Temporary<HTMLCollection> {
-        HTMLCollection::new(window, Live(root.unrooted(), filter))
+        HTMLCollection::new(window, Live(JS::from_rooted(root), filter))
     }
 
     pub fn by_tag_name(window: &JSRef<Window>, root: &JSRef<Node>, tag: DOMString)
                        -> Temporary<HTMLCollection> {
         struct TagNameFilter {
             tag: DOMString
         }
         impl CollectionFilter for TagNameFilter {
--- a/servo/src/components/script/dom/node.rs
+++ b/servo/src/components/script/dom/node.rs
@@ -814,17 +814,17 @@ pub struct NodeIterator {
     include_descendants_of_void: bool
 }
 
 impl NodeIterator {
     pub fn new<'a>(start_node: &JSRef<'a, Node>,
                    include_start: bool,
                    include_descendants_of_void: bool) -> NodeIterator {
         NodeIterator {
-            start_node: start_node.unrooted(),
+            start_node: JS::from_rooted(start_node),
             current_node: None,
             depth: 0,
             include_start: include_start,
             include_descendants_of_void: include_descendants_of_void
         }
     }
 
     fn next_child<'b>(&self, node: &JSRef<'b, Node>) -> Option<JSRef<Node>> {
@@ -844,42 +844,42 @@ impl NodeIterator {
 impl<'a> Iterator<JSRef<'a, Node>> for NodeIterator {
     fn next(&mut self) -> Option<JSRef<Node>> {
         self.current_node = match self.current_node.as_ref().map(|node| node.root()) {
             None => {
                 if self.include_start {
                     Some(self.start_node)
                 } else {
                     self.next_child(&*self.start_node.root())
-                        .map(|child| child.unrooted())
+                        .map(|child| JS::from_rooted(&child))
                 }
             },
             Some(node) => {
                 match self.next_child(&*node) {
                     Some(child) => {
                         self.depth += 1;
-                        Some(child.unrooted())
+                        Some(JS::from_rooted(&child))
                     },
-                    None if node.deref().unrooted() == self.start_node => None,
+                    None if JS::from_rooted(&*node) == self.start_node => None,
                     None => {
                         match node.deref().next_sibling().root() {
-                            Some(sibling) => Some(sibling.deref().unrooted()),
+                            Some(sibling) => Some(JS::from_rooted(&*sibling)),
                             None => {
                                 let mut candidate = node.deref().clone();
                                 while candidate.next_sibling().is_none() {
                                     candidate = (*candidate.parent_node()
                                                           .expect("Got to root without reaching start node")
                                                           .root()).clone();
                                     self.depth -= 1;
-                                    if candidate.unrooted() == self.start_node {
+                                    if JS::from_rooted(&candidate) == self.start_node {
                                         break;
                                     }
                                 }
-                                if candidate.unrooted() != self.start_node {
-                                    candidate.next_sibling().map(|node| node.root().unrooted())
+                                if JS::from_rooted(&candidate) != self.start_node {
+                                    candidate.next_sibling().map(|node| JS::from_rooted(node.root().deref()))
                                 } else {
                                     None
                                 }
                             }
                         }
                     }
                 }
             }
@@ -935,17 +935,16 @@ impl Node {
             eventtarget: EventTarget::new_inherited(NodeTargetTypeId(type_id)),
             type_id: type_id,
 
             parent_node: Cell::new(None),
             first_child: Cell::new(None),
             last_child: Cell::new(None),
             next_sibling: Cell::new(None),
             prev_sibling: Cell::new(None),
-
             owner_doc: Cell::new(doc.unrooted()),
             child_list: Cell::new(None),
 
             flags: Untraceable::new(RefCell::new(NodeFlags::new(type_id))),
 
             layout_data: LayoutDataRef::new(),
         }
     }
@@ -1238,17 +1237,17 @@ impl Node {
     }
 
     // http://dom.spec.whatwg.org/#concept-node-clone
     pub fn clone(node: &JSRef<Node>, maybe_doc: Option<&JSRef<Document>>,
                  clone_children: CloneChildrenFlag) -> Temporary<Node> {
 
         // Step 1.
         let mut document = match maybe_doc {
-            Some(doc) => doc.unrooted().root(),
+            Some(doc) => JS::from_rooted(doc).root(),
             None => node.owner_doc().root()
         };
 
         // Step 2.
         // XXXabinader: clone() for each node as trait?
         let mut copy: Root<Node> = match node.type_id() {
             DoctypeNodeTypeId => {
                 let doctype: &JSRef<DocumentType> = DocumentTypeCast::to_ref(node).unwrap();
@@ -1299,19 +1298,19 @@ impl Node {
                                                     pi.characterdata.data.deref().borrow().clone(), &*document);
                 NodeCast::from_temporary(pi)
             },
         }.root();
 
         // Step 3.
         let document = if copy.is_document() {
             let doc: &JSRef<Document> = DocumentCast::to_ref(&*copy).unwrap();
-            doc.unrooted().root()
+            JS::from_rooted(doc).root()
         } else {
-            document.unrooted().root()
+            JS::from_rooted(&*document).root()
         };
         assert!(&*copy.owner_doc().root() == &*document);
 
         // Step 4 (some data already copied in step 2).
         match node.type_id() {
             DocumentNodeTypeId => {
                 let node_doc: &JSRef<Document> = DocumentCast::to_ref(node).unwrap();
                 let copy_doc: &JSRef<Document> = DocumentCast::to_ref(&*copy).unwrap();
--- a/servo/src/components/script/dom/nodelist.rs
+++ b/servo/src/components/script/dom/nodelist.rs
@@ -22,32 +22,32 @@ pub struct NodeList {
 }
 
 impl NodeList {
     pub fn new_inherited(window: &JSRef<Window>,
                          list_type: NodeListType) -> NodeList {
         NodeList {
             list_type: list_type,
             reflector_: Reflector::new(),
-            window: window.unrooted()
+            window: JS::from_rooted(window)
         }
     }
 
     pub fn new(window: &JSRef<Window>,
                list_type: NodeListType) -> Temporary<NodeList> {
         reflect_dom_object(box NodeList::new_inherited(window, list_type),
                            window, NodeListBinding::Wrap)
     }
 
     pub fn new_simple_list(window: &JSRef<Window>, elements: Vec<JSRef<Node>>) -> Temporary<NodeList> {
-        NodeList::new(window, Simple(elements.iter().map(|element| element.unrooted()).collect()))
+        NodeList::new(window, Simple(elements.iter().map(|element| JS::from_rooted(element)).collect()))
     }
 
     pub fn new_child_list(window: &JSRef<Window>, node: &JSRef<Node>) -> Temporary<NodeList> {
-        NodeList::new(window, Children(node.unrooted()))
+        NodeList::new(window, Children(JS::from_rooted(node)))
     }
 }
 
 pub trait NodeListMethods {
     fn Length(&self) -> u32;
     fn Item(&self, index: u32) -> Option<Temporary<Node>>;
     fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Temporary<Node>>;
 }
--- a/servo/src/components/script/dom/performance.rs
+++ b/servo/src/components/script/dom/performance.rs
@@ -14,17 +14,17 @@ pub type DOMHighResTimeStamp = f64;
 #[deriving(Encodable)]
 pub struct Performance {
     pub reflector_: Reflector,
     pub timing: JS<PerformanceTiming>,
 }
 
 impl Performance {
     fn new_inherited(window: &JSRef<Window>) -> Performance {
-        let timing = PerformanceTiming::new(window).root().root_ref().unrooted();
+        let timing = JS::from_rooted(&PerformanceTiming::new(window).root().root_ref());
         Performance {
             reflector_: Reflector::new(),
             timing: timing,
         }
     }
 
     pub fn new(window: &JSRef<Window>) -> Temporary<Performance> {
         let performance = Performance::new_inherited(window);
--- a/servo/src/components/script/dom/validitystate.rs
+++ b/servo/src/components/script/dom/validitystate.rs
@@ -14,17 +14,17 @@ pub struct ValidityState {
     pub window: Cell<JS<Window>>,
     pub state: u8,
 }
 
 impl ValidityState {
     pub fn new_inherited(window: &JSRef<Window>) -> ValidityState {
         ValidityState {
             reflector_: Reflector::new(),
-            window: Cell::new(window.unrooted()),
+            window: Cell::new(JS::from_rooted(window)),
             state: 0,
         }
     }
 
     pub fn new(window: &JSRef<Window>) -> Temporary<ValidityState> {
         reflect_dom_object(box ValidityState::new_inherited(window),
                            window,
                            ValidityStateBinding::Wrap)
--- a/servo/src/components/script/dom/xmlhttprequest.rs
+++ b/servo/src/components/script/dom/xmlhttprequest.rs
@@ -4,17 +4,17 @@
 
 use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
 use dom::bindings::codegen::Bindings::XMLHttpRequestBinding;
 use dom::bindings::codegen::Bindings::XMLHttpRequestBinding::XMLHttpRequestResponseType;
 use dom::bindings::codegen::Bindings::XMLHttpRequestBinding::XMLHttpRequestResponseTypeValues::{_empty, Json, Text};
 use dom::bindings::codegen::InheritTypes::{EventCast, EventTargetCast, XMLHttpRequestDerived};
 use dom::bindings::conversions::ToJSValConvertible;
 use dom::bindings::error::{ErrorResult, Fallible, InvalidState, InvalidAccess, Network, Syntax, Security};
-use dom::bindings::js::{JS, JSRef, Temporary, OptionalSettable, OptionalRootedRootable};
+use dom::bindings::js::{JS, JSRef, Temporary, OptionalRootedRootable};
 use dom::bindings::str::ByteString;
 use dom::bindings::trace::Untraceable;
 use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
 use dom::document::Document;
 use dom::event::Event;
 use dom::eventtarget::{EventTarget, EventTargetHelpers, XMLHttpRequestTargetTypeId};
 use dom::progressevent::ProgressEvent;
 use dom::window::Window;
@@ -101,17 +101,17 @@ impl<'a,'b> SyncOrAsync<'a,'b> {
     }
 }
 #[deriving(Encodable)]
 pub struct XMLHttpRequest {
     eventtarget: XMLHttpRequestEventTarget,
     ready_state: XMLHttpRequestState,
     timeout: u32,
     with_credentials: bool,
-    upload: Cell<Option<JS<XMLHttpRequestUpload>>>,
+    upload: Cell<JS<XMLHttpRequestUpload>>,
     response_url: DOMString,
     status: u16,
     status_text: ByteString,
     response: ByteString,
     response_type: XMLHttpRequestResponseType,
     response_xml: Cell<Option<JS<Document>>>,
     response_headers: Untraceable<ResponseHeaderCollection>,
 
@@ -131,17 +131,17 @@ pub struct XMLHttpRequest {
 
 impl XMLHttpRequest {
     pub fn new_inherited(owner: &JSRef<Window>) -> XMLHttpRequest {
         let xhr = XMLHttpRequest {
             eventtarget: XMLHttpRequestEventTarget::new_inherited(XMLHttpRequestTypeId),
             ready_state: Unsent,
             timeout: 0u32,
             with_credentials: false,
-            upload: Cell::new(None),
+            upload: Cell::new(JS::from_rooted(&XMLHttpRequestUpload::new(owner))),
             response_url: "".to_string(),
             status: 0,
             status_text: ByteString::new(vec!()),
             response: ByteString::new(vec!()),
             response_type: _empty,
             response_xml: Cell::new(None),
             response_headers: Untraceable::new(ResponseHeaderCollection::new()),
 
@@ -150,20 +150,19 @@ impl XMLHttpRequest {
             request_headers: Untraceable::new(RequestHeaderCollection::new()),
             request_body: "".to_string(),
             sync: false,
             send_flag: false,
 
             upload_complete: false,
             upload_events: false,
 
-            global: owner.unrooted(),
+            global: JS::from_rooted(owner),
             pinned: false,
         };
-        xhr.upload.assign(Some(XMLHttpRequestUpload::new(owner)));
         xhr
     }
     pub fn new(window: &JSRef<Window>) -> Temporary<XMLHttpRequest> {
         reflect_dom_object(box XMLHttpRequest::new_inherited(window),
                            window,
                            XMLHttpRequestBinding::Wrap)
     }
     pub fn Constructor(owner: &JSRef<Window>) -> Fallible<Temporary<XMLHttpRequest>> {
@@ -402,17 +401,17 @@ impl<'a> XMLHttpRequestMethods<'a> for J
     }
     fn WithCredentials(&self) -> bool {
         self.with_credentials
     }
     fn SetWithCredentials(&mut self, with_credentials: bool) {
         self.with_credentials = with_credentials
     }
     fn Upload(&self) -> Temporary<XMLHttpRequestUpload> {
-        Temporary::new(self.upload.get().get_ref().clone())
+        Temporary::new(self.upload.get())
     }
     fn Send(&mut self, data: Option<DOMString>) -> ErrorResult {
         if self.ready_state != Opened || self.send_flag {
             return Err(InvalidState); // Step 1, 2
         }
 
         let data = match *self.request_method {
             Get | Head => None, // Step 3
@@ -424,17 +423,17 @@ impl<'a> XMLHttpRequestMethods<'a> for J
         // Step 7
         self.upload_complete = match data {
             None => true,
             Some (ref s) if s.len() == 0 => true,
             _ => false
         };
         if !self.sync {
             // Step 8
-            let upload_target = &*self.upload.get().root().unwrap();
+            let upload_target = &*self.upload.get().root();
             let event_target: &JSRef<EventTarget> = EventTargetCast::from_ref(upload_target);
             if event_target.has_handlers() {
                 self.upload_events = true;
             }
 
             // Step 9
             self.send_flag = true;
             self.dispatch_response_progress_event("loadstart".to_string());
@@ -729,20 +728,20 @@ impl<'a> PrivateXMLHttpRequestHelpers fo
         let maybe_header: Option<Header> = HeaderEnum::value_from_stream(
                                                                 String::from_str(name.as_slice()),
                                                                 &mut HeaderValueByteIterator::new(&mut reader));
         collection.insert(maybe_header.unwrap());
     }
 
     fn dispatch_progress_event(&self, upload: bool, type_: DOMString, loaded: u64, total: Option<u64>) {
         let win = &*self.global.root();
-        let upload_target = &*self.upload.get().root().unwrap();
-        let progressevent = ProgressEvent::new(win, type_, false, false,
-                                               total.is_some(), loaded,
-                                               total.unwrap_or(0)).root();
+        let upload_target = &*self.upload.get().root();
+        let mut progressevent = ProgressEvent::new(win, type_, false, false,
+                                                   total.is_some(), loaded,
+                                                   total.unwrap_or(0)).root();
         let target: &JSRef<EventTarget> = if upload {
             EventTargetCast::from_ref(upload_target)
         } else {
             EventTargetCast::from_ref(self)
         };
         let event: &JSRef<Event> = EventCast::from_ref(&*progressevent);
         target.dispatch_event_with_target(None, event).ok();
     }
--- a/servo/src/components/script/script_task.rs
+++ b/servo/src/components/script/script_task.rs
@@ -566,18 +566,18 @@ impl ScriptTask {
         let HtmlParserResult {
             discovery_port
         } = html_parsing_result;
 
         {
             // Create the root frame.
             let mut frame = page.mut_frame();
             *frame = Some(Frame {
-                document: document.deref().unrooted(),
-                window: window.deref().unrooted(),
+                document: JS::from_rooted(document.deref()),
+                window: JS::from_rooted(window.deref()),
             });
         }
 
         // Send style sheets over to layout.
         //
         // FIXME: These should be streamed to layout as they're parsed. We don't need to stop here
         // in the script task.
 
@@ -772,22 +772,22 @@ impl ScriptTask {
                             let maybe_node = temp_node.root().ancestors().find(|node| node.is_element());
                             match maybe_node {
                                 Some(node) => {
                                     node.set_hover_state(true);
 
                                     match *mouse_over_targets {
                                         Some(ref mouse_over_targets) => {
                                             if !target_compare {
-                                                target_compare = !mouse_over_targets.contains(&node.unrooted());
+                                                target_compare = !mouse_over_targets.contains(&JS::from_rooted(&node));
                                             }
                                         }
                                         None => {}
                                     }
-                                    target_list.push(node.unrooted());
+                                    target_list.push(JS::from_rooted(&node));
                                 }
                                 None => {}
                             }
                         }
                         match *mouse_over_targets {
                             Some(ref mouse_over_targets) => {
                                 if mouse_over_targets.len() != target_list.len() {
                                     target_compare = true;